Problem
I am about to finish a big project and I found out that my app is slow on 3G when it comes to downloading data from a server and displaying it. I read about Volley last week, and I soon implemented it to see if it's faster than Asynctask. Not exactly. The response from both methods are very slow on 3G (fast on WIFI), and when I say very slow, I mean users need to wait 0.8-3.5s till the data is displayed.
So I checked the code and found that the problem is with the response. After the response has been received on Android side, ListView population and display of data happens under 0.3s, but till the response is received, users need to wait.
I am using a VPS with HTTPS connection.
What I tried
I tried setting
HttpProtocolParams.setVersion(httpparams, HttpVersion.HTTP_1_1);
and
httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
based on this post.
- I tried removing the whole db connection and query and just posting the response in php meaning the whole content was the script was this:
echo "[[{...content of the query }]]
and in this case the response was much faster (but I cannot say 100%)!
- I tried putting the response (try No. 2) on a HTTP shared server (so not the query, because I didn't want to mock with databases), and I don't know if that means anything but the response was about 0.8s in both HTTP and HTTPS server.
Here's my code With Asynctask
public class DownloadBucket extends AsyncTask<String, Void, ArrayList<String>> {
@Override
protected void onPostExecute(ArrayList<String> result) {
myadapter = new MyAdapter(BucketUsers.this, arr_users_id, arr_users_username, arr_users_firstname, arr_users_lastname, arr_users_photo, arr_users_followed);
lv.setAdapter(myadapter);
}
actionBar.show();
@Override
protected void onPreExecute() {
actionBar.hide();
}
@Override
protected ArrayList<String> doInBackground(String... params) {
try{
HttpParams httpparams = new BasicHttpParams();
//HttpProtocolParams.setVersion(httpparams, HttpVersion.HTTP_1_1);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = null;
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
Log.i("At bucketid", bucketid + "");
Log.i("At session_userid", session_userid + "");
nameValuePairs.add(new BasicNameValuePair("session_userid", session_userid));
nameValuePairs.add(new BasicNameValuePair("bucketid", bucketid));
nameValuePairs.add(new BasicNameValuePair("start", params[1]));
nameValuePairs.add(new BasicNameValuePair("finish", params[2]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("error", "Error in http connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
Log.i("sb", sb + "");
Bresult=sb.toString();
Log.i("Bresult", Bresult + "");
}catch(Exception e){
Log.e("error", "Error converting result "+e.toString());
}
ArrayList<String> result = new ArrayList<String>();
try {
jArray = new JSONArray(Bresult);
for(int i=0;i<jArray.length();i++){
JSONArray innerJsonArray = jArray.getJSONArray(i);
for(int j=0;j<innerJsonArray.length();j++){
JSONObject jsonObject = innerJsonArray.getJSONObject(j);
arr_users_id.add(jsonObject.getString("ID"));
arr_users_username.add(jsonObject.getString("USERNAME"));
arr_users_firstname.add(jsonObject.getString("NAME"));
arr_users_lastname.add(jsonObject.getString("NAME2"));
arr_users_photo.add(jsonObject.getString("PHOTO"));
arr_users_followed.add(jsonObject.getString("DO_I_FOLLOW_HIM"));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
With Volley
private void makeJsonArrayRequest(final String list, final String start, final String finish) {
StringRequest postReq = new StringRequest(Method.POST, loadusers, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
//Here we are already at 0.8-3.5 seconds!
//Everything after this happens very fast
if (response.length() > 10) {
try {
jArray = new JSONArray(response);
for(int i=0;i<jArray.length();i++){
JSONArray innerJsonArray = jArray.getJSONArray(i);
for(int j=0;j<innerJsonArray.length();j++){
JSONObject jsonObject = innerJsonArray.getJSONObject(j);
arr_users_id.add(jsonObject.getString("ID"));
arr_users_username.add(jsonObject.getString("USERNAME"));
arr_users_firstname.add(jsonObject.getString("NAME"));
arr_users_lastname.add(jsonObject.getString("NAME2"));
arr_users_photo.add(jsonObject.getString("PHOTO"));
arr_users_followed.add(jsonObject.getString("DO_I_FOLLOW_HIM"));
}
}
pb.setVisibility(View.GONE);
loading_ll.setVisibility(View.GONE);
llMain.setVisibility(View.VISIBLE);
if (arr_users_id.size() < 31) {
myadapter = new MyAdapter(BucketUsers.this, arr_users_id, arr_users_username, arr_users_firstname, arr_users_lastname, arr_users_photo, arr_users_followed);
lv.setAdapter(myadapter);
} else {
myadapter.notifyDataSetChanged();
}
actionBar.show();
} catch (JSONException e) {
e.printStackTrace();
}
} else {
all_items_downloaded = true;
lv.removeFooterView(loadMoreView);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// System.out.println("Error ["+error+"]");
Log.i("VOLLEY_ERROR", error.toString());
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("session_userid", session_userid);
params.put("bucketid", bucketid);
params.put("start", start);
params.put("finish", finish);
return params;
}
};
postReq.setShouldCache(false);
AppController.getInstance().addToRequestQueue(postReq);
}
PHP
<?php
require_once($_SERVER['SERVER_ROOT'].'mysecretdbdata.php');
$response = array();
try {
$conn = new PDO("mysql:host=$host;dbname=$database", $dbusername, $dbpassword, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response = '0';
[QUERY]
print(json_encode($output));
?>
Is this normal? Are there any ways to speed things up? I don't know how it works, but e.g. with Pinterest when you click on an object, the image and the data is displayed immediately. Users make their expections based on top apps and even I don't like using my own app when it's slow.