httpurlconnection is very slow on Android 4.2
Asked Answered
A

2

12

I can succesfully connect, send and receive data by using httpurlconnection. But it takes very long time to load all the data on my phone (Samsung s4, 4.2) and on android 4.2 emulator. But it takes almost 1-2 seconds (which is very fast) to load pics on Android 2.3.x emulator. Faster than my galaxy s4 on http connection.

I'm using AsyncTask and my code works fine on both. It is just slow on android 4.2s. I tried removing chunkedStreaming, keep alive, changing timeout values etc. but still no success

Here is my code

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                 urlConnection.setRequestMethod("POST");
                 urlConnection.setDoOutput(true);
                 urlConnection.setDoInput(true); 

                 urlConnection.setUseCaches(false);
                 urlConnection.setChunkedStreamingMode(0);
                 urlConnection.setRequestProperty("Connection", "Keep-Alive");
                 urlConnection.setConnectTimeout(6000);
                 urlConnection.setReadTimeout(6000);
                 urlConnection.setRequestProperty("Content-Type", "multipart/form-data;charset=UTF-8;boundary="+boundary);

                 urlConnection.connect();

Are there any differences between 4.2's and 2.3.x's httpurlconnections? Whats wrong here

UPDATE!

I tested by using Log.e() to see which line takes most time.

///// other staff
////......
                     Log.e("HTTP","3");

                 if (isCancelled())
                        return (null); // don't forget to terminate this method
                 Log.e("HTTP","3");
                 //Output
                    DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );
                    //Send Passcode
                    Log.e("HTTP","4");

Between 3 and 4, 5-6 second passes on the line

DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );

UPDATE!!

That waiting time (see previous update) is related to the urlConnection.setConnectTimeout(6000);

When I make Timeout 1000, then connection responses quickly (waiting 1 second for the line)

DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );

No idea why this is happening

Anatto answered 8/11, 2013 at 23:10 Comment(2)
you don't need to setDoInput, also, setting DoOutput to true automatically sets the method to POST so you don't need to setRequestMethod. I never needed to set any timeouts, requestProperty or chunkedStreamingMode, have you tried removing those? I also don't use .connect(), I getOutputStream() and getInputStream() right after setting the request parameters.Covey
do you .disconnect() at the end? a common way is to wrap the urlConnection code with try/catch/finally block and call urlConnection.disconnect() in finallyCovey
W
4

Set urlConnection.setConnectTimeout() to a lower timeout.

The class documentation for URLConnection.setConnectTimeout() says:

Sets the maximum time in milliseconds to wait while connecting. Connecting to a server will fail with a SocketTimeoutException if the timeout elapses before a connection is established. The default value of 0 causes us to do a blocking connect. This does not mean we will never time out, but it probably means you'll get a TCP timeout after several minutes.

Warning: if the hostname resolves to multiple IP addresses, this client will try each in RFC 3484 order. If connecting to each of these addresses fails, multiple timeouts will elapse before the connect attempt throws an exception. Host names that support both IPv6 and IPv4 always have at least 2 IP addresses.

I originally had mine set to urlConnection.setConnectTimeout(30000); and then changed it to urlConnection.setConnectTimeout(1000). Immediately, I saw quicker results.

Hope this helps!

Wexler answered 20/11, 2013 at 22:54 Comment(1)
Note: I realize that this is a perceived effect and that I didn't actually attempt to find the root cause. But, I figured it could help people nonetheless.Wexler
I
1

You mentionned you are using AsyncTask, are you trying to run several tasks at the same time ?

If that's the case, you should be aware that starting with Android 4.0, AsyncTasks are serialized by default. That means the executor will run one task at a time.

If you want to keep the previous behavior, you can use the following construct:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
  myTask.execute();
}

See this blog post for more information:
http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html

Isodynamic answered 9/11, 2013 at 0:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.