Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient stalls for long periods of time, even with timeout parameters set

I have an app that is doing a non trivial amount of downloading of thumbnail images and other resources from a remote service.

I'm using a single instance of DefaultHttpClient and a custom class that I wrote that schedules all of my downloads. All downloading is run in serial on background threads via AsyncTask. I don't re-run my download routine until onPostExecute gets executed in the AsyncTask.

This often works perfectly. If I queue up 20 images, my scheduler does its thing just fine. However, I run into cases where the procedure just stalls at the point of calling client.execute (where client is my instance of DefaultHttpClient). I can inexplicably resuscitate the process by navigating around the app and doing random actions (scrolling a list, navigating back and forth between activities, etc). It's as if something I'm doing is sending a "wake up" message to a thread that has stalled or deadlocked.

I've added an obnoxious amount of logging at all moving parts of my application to see if something external to this procedure is causing some kind of deadlock condition. I view LogCat by pid to see if anything else is happening in my process at the point of stalling or at the point of resuming, and I don't see anything whatsoever out of the ordinary. The weirdest part about this is that I can duplicate the exact condition over and over.

FWIW, I have set socket timeouts and connection timeouts on both the HttpClient instance and the HttpGet instance that I pass to the execute method. This does not cause the execute method to return early or throw an exception or anything like that. When the procedure "kicks back in", HttpClient.execute returns a valid HttpResponse and everything operates as normal.

Any ideas on things I can debug to find out where this is getting tripped up? I recognize that this is a very specific condition, but are there any advanced methods for specifically debugging DefaultHttpClient or http traffic in Android in general?

Thanks!

like image 267
Rich Avatar asked Aug 17 '11 01:08

Rich


1 Answers

Do you share the same HttpClient across threads? It's not thread-safe by default, so you might want to check that. Most likely it's blocking on I/O though, so you should do some wire debugging. You can use something like this to enable HttpClient wire dump logs:

Logger.getLogger("org.apache.http.wire").setLevel(Level.FINEST);
Logger.getLogger("org.apache.http.headers").setLevel(FINEST);
Logger.getLogger("httpclient.wire.header").setLevel(FINEST);
Logger.getLogger("httpclient.wire.content").setLevel(FINEST);

System.setProperty("org.apache.commons.logging.Log",
     "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug");

To enable it, execute the following shell commands. Wire logs will be output to logcat:

adb shell setprop log.tag.org.apache.http VERBOSE 
adb shell setprop log.tag.org.apache.http.wire VERBOSE 
adb shell setprop log.tag.org.apache.http.headers VERBOSE
like image 94
Nikolay Elenkov Avatar answered Oct 24 '22 00:10

Nikolay Elenkov