0

I am making an app for Android. I like to make the rest calls as quick as possible. When I get my results as XML it takes 5 seconds (!) to get a simple xml like this:

   <souvenirs>
     <souvenir>
       <id>1</id>
       <name>Example 1</name>
       <rating>3.4</rating>
       <photourl>/images/example.jpg</photourl>
       <price>3.50</price>
     </souvenir>
     <souvenir>
       <id>2</id>
       <name>Example 2</name>
       <rating>2.4</rating>
       <photourl>/images/example.jpg</photourl>
       <price>8.50</price>
       </souvenir>
   </souvenirs>

So I tried it with JSON. But that takes also about 5 seconds to retrieve.

I load the XML in android with the following code:

        URL url = new URL("http://example.nu?method=getAllSouvenirs");
            URLConnection conn = url.openConnection();
            long t=System.currentTimeMillis();

            InputStream ins = conn.getInputStream();
            Log.d("info", String.valueOf((System.currentTimeMillis()-t)));

The log says it takes about 5000 ms to get the inputstream.. Is there any way to speed this up? does anybody knows which technique the Android Market uses? This loads way faster than my app..

Thanks in advance! :)

Martijn538
  • 51
  • 1
  • 1
  • 4

3 Answers3

2

When you try to get the data "manually" - via browser or via other means (wget, curl) how long does it take there.

On Android you also should take the mobile network into consideration that is usually significantly slower than for a desktop computer. Also latencies are bigger.

To me this sounds a lot like issues in the backend (e.g. trying to resolve the IP of the client and thus taking lots of time).

Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119
1

use Apache HttpClient instead of URLConnection: Apache http client or URLConnection

EDIT(2012-02-07): no longer true on newer android platform please read: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Community
  • 1
  • 1
Selvin
  • 6,598
  • 3
  • 37
  • 43
  • 1
    No matter if you use HttpClient or UrlConnection or carrier pigeons that should not take 5sec with a decent remote. – Heiko Rupp Apr 20 '11 at 11:33
  • @Heiko Rupp true ... but HttpClient seems to be quicker then UrlConnection – Selvin Apr 20 '11 at 11:41
  • So, I tried HttpClient now. results: 04-20 14:00:47.011: DEBUG/info(7126): json call duration: 3312 04-20 14:01:26.621: DEBUG/info(7126): json call duration: 3207 04-20 14:01:27.631: DEBUG/info(7126): json call duration: 1009 04-20 14:01:42.521: DEBUG/info(7126): json call duration: 2103 04-20 14:01:43.861: DEBUG/info(7126): json call duration: 1333 04-20 14:02:00.651: DEBUG/info(7126): json call duration: 5148 04-20 14:02:01.841: DEBUG/info(7126): json call duration: 1190 – Martijn538 Apr 20 '11 at 12:01
  • @Martijn538 so now call takes aprox 2 sec. ? – Selvin Apr 20 '11 at 12:06
  • When I open my activity and I restart it immediately (by pressing back and forth in the menu it's around 2 seconds.. But when I wait for half a minute it's around the 3/4 seconds.. – Martijn538 Apr 20 '11 at 12:10
0

Maybe that is how it is implemented and you can't do nothing. That is my guess. My opinion is to do all connection based stuff on your own thread (to put in in background) and in foreground (main UI thread) entertain user. :)

I have played a little bit around this and it works fast enough for me... Here is my code:

private static HttpResponse doPost(String url, JSONStringer json) {
    try {
        HttpPost request = new HttpPost(url);
        StringEntity entity;
        entity = new StringEntity(json.toString());

        entity.setContentType("application/json;charset=UTF-8");
        entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));
        request.setEntity(entity);

        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(request);
            return response;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

And somewhere else I call that method like:

HttpResponse httpResponse = doPost(url, json);
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));

It works fine for me...

zmeda
  • 2,909
  • 9
  • 36
  • 56
  • Thanks, when I execute the url on my computer, it only takes about 100ms, so that isn't the problem. I'm just wondering how it's possible to make my app as fast as the Android Market.. – Martijn538 Apr 20 '11 at 11:43
  • @Martijn try this from the browser on your mobile. – Heiko Rupp Apr 20 '11 at 12:01
  • I tried and this is faster than using it in my app. Right now I'm trying to implement Keepalive to my httpClient. Does anybody know how to do this? I heard that reusing the HttpClient in the App improves the speed. I reused my HttpClient by creating it in the Main Activity. Then, when starting another Activity, I passed it to my Intent (putExtra) and made my HttpClient Parceable.. Is this the correct way to do it? – Martijn538 Apr 20 '11 at 12:52
  • Based on the process I describe above, it takes me 307 milliseconds to call `doPost` method and 2 milliseconds for `BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));` I have tried this on emulator. If I set speed and latency of emulator to GPRS numbers are 628 and 3 milliseconds respectfully. – zmeda Apr 20 '11 at 13:59
  • It occurs to me that only the first call is taking long. Now I implemented my own restclient AND the method of ZMeda. I get the following results: call duration: 2401 json call duration: 416 call duration: 1485 json call duration: 908 call duration: 1142 json call duration: 864 call duration: 1229 json call duration: 635 call duration: 1459 json call duration: 575 Isn't there any way I can speed this more up? if you guys want to try the url : http://91.121.69.135/~jpmwebd/android/?method=getAllSouvenirs – Martijn538 Apr 20 '11 at 14:00
  • When I test it via the emulator on GPRS: 04-20 14:10:09.146: DEBUG/info(518): call duration : 2790 04-20 14:10:28.196: DEBUG/info(518): call duration : 902 04-20 14:10:48.467: DEBUG/info(518): call duration : 1767 – Martijn538 Apr 20 '11 at 14:11
  • So I think I found the problem: When I put my code in an AsyncTask, it takes 2500ms, but when I put my code simply in the oncreate method, it takes 400ms! Don't know how this is possible, but i won't use an asynctask for it anymore.. – Martijn538 Apr 20 '11 at 14:25