1

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

  1. I tried setting

    HttpProtocolParams.setVersion(httpparams, HttpVersion.HTTP_1_1);

and

httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

based on this post.

  1. 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%)!

  1. 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.

Community
  • 1
  • 1
erdomester
  • 11,789
  • 32
  • 132
  • 234
  • 1
    `The response from both methods are very slow on 3G (fast on WIFI)` sounds like you solved it your self, your 3G connection is slow. Not sure what you want us to do about that – tyczj Jan 23 '15 at 16:17
  • What's the payload? How large is the result? – 323go Jan 23 '15 at 16:19
  • If my 3G connection is slow (DL: 7.7 Mbps, UL: 1.56 Mbps), then why do other apps work fast? Since when is this connection considered as slow? – erdomester Jan 23 '15 at 16:22
  • 1
    @erdomester because their content is probably cached – tyczj Jan 23 '15 at 16:23
  • Would you elaborate? If the content is cached then it should work super fast – erdomester Jan 23 '15 at 16:29
  • You never said what you payload is and how large it is like @323go said, the larger the payload the longer it will take obviously. All signs point to your connection since you say it works fine when on wifi – tyczj Jan 23 '15 at 16:35
  • My WIFI speed now: DL: 10.14 Mbps, UL: 1 Mbps, so not much better than 3G. How can I measure the payload? The query is a few selects, subselects and joins of 5 tables resulting in 30 rows by 10 columns, so not much and there isn't many data in the database either. – erdomester Jan 23 '15 at 16:40

0 Answers0