2011-08-17 35 views
5

我有一个应用程序正在从远程服务中下载缩略图图像和其他资源。即使设置了超时参数,HttpClient也会停止很长时间

我正在使用DefaultHttpClient的单个实例和我编写的自定义类来安排我的所有下载。所有下载都通过AsyncTask在后台线程上串行运行。在AsyncTask中执行onPostExecute之前,我不会重新运行我的下载例程。

这通常是完美的。如果我排队20个图像,我的调度程序就很好。但是,我遇到过程只是在调用client.execute(其中客户端是我的DefaultHttpClient实例)时停顿的情况。我可以通过在应用程序中导航并进行随机操作(滚动列表,在活动之间来回导航等)来令人莫名其妙地恢复过程。 这就好像我正在做的事情是发送一个“唤醒”消息给已经停顿或死锁的线程。

我在应用程序的所有移动部分添加了令人讨厌的日志记录,以查看此过程的外部是否导致某种死锁情况。我通过pid查看LogCat,看看我的进程中是否有任何其他事情正在停滞或恢复的过程中发生,而且我看不到什么与众不同的事情。关于这个最奇怪的部分是我可以一遍又一遍复制确切的情况。

FWIW,我在HttpClient实例和传递给execute方法的HttpGet实例上都设置了套接字超时和连接超时。这不会导致execute方法提前返回或抛出异常或类似的东西。当过程“重新开始”时,HttpClient.execute将返回有效的HttpResponse,并且所有操作都正常进行。

任何关于事物的想法,我可以调试,以找出这是越来越绊倒?我认识到这是一个非常具体的条件,但是否有任何先进的方法来专门调试Android中的DefaultHttpClient或http流量?

谢谢!

回答

5

你是否跨线程共享相同的HttpClient?它默认情况下不是线程安全的,所以你可能想要检查它。尽管它很可能阻塞了I/O,所以你应该做一些线程调试。您可以使用这样的事情,使HttpClient的电线转储日志:

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"); 

要启用它,执行下面的shell命令。电线日志将输出到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 
+0

感谢您回复......难以得到这些具体和冗长的问题的答案。我会尝试伐木,但我相信你指出我正确的方向。我使用AsyncTask,它可以从线程池中获得线程......这可能会导致一些问题。我将尝试使用单个Thread派生类,以便在diff线程上同时调用HttpClient.execute。我敢打赌,即使在我再次运行我的循环之前执行返回,也可能有一些清理在下一个线程进入之前尚未完成运行。 – Rich

+0

顺便提一下,我已经添加了这段代码,但我没有看到LogCat中的任何其他日志。还有什么更多?它是将日志转储到文件中,还是应该在LogCat中看到? – Rich

+0

应该去logcat。确保你在你的应用程序代码之前执行此操作,例如在静态初始化程序中。 –

-2

我以前有过类似的问题。 当我尝试执行HTTP获取队列时,方法httpClient.execute(get);将不会返回响应,如死锁。

HttpResponse response = httpClient.execute(get); 
HttpEntity entity = response.getEntity(); 

这是我的代码,我所做的就是打电话entity.consumeContent();然后它就起作用了。

+0

没有真正回答这个问题。 –

相关问题