Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 即使设置了超时参数,HttpClient也会长时间暂停_Java_Android_Httpclient - Fatal编程技术网

Java 即使设置了超时参数,HttpClient也会长时间暂停

Java 即使设置了超时参数,HttpClient也会长时间暂停,java,android,httpclient,Java,Android,Httpclient,我有一个应用程序,可以从远程服务下载大量的缩略图和其他资源 我使用的是DefaultHttpClient的一个实例和我编写的一个定制类,它安排了我所有的下载。所有下载都通过AsyncTask在后台线程上串行运行。在AsyncTask中执行onPostExecute之前,我不会重新运行下载例程 这通常非常有效。如果我把20个图像排成一列,我的调度程序就会做得很好。但是,我遇到这样的情况,即过程在调用client.execute时暂停(其中client是我的DefaultHttpClient实例)。

我有一个应用程序,可以从远程服务下载大量的缩略图和其他资源

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

这通常非常有效。如果我把20个图像排成一列,我的调度程序就会做得很好。但是,我遇到这样的情况,即过程在调用client.execute时暂停(其中client是我的DefaultHttpClient实例)。我可以通过在应用程序中导航并执行随机操作(滚动列表、在活动之间来回导航等)来莫名其妙地恢复进程就好像我正在做的事情是向已暂停或死锁的线程发送“唤醒”消息。

我在应用程序的所有移动部分添加了大量令人讨厌的日志记录,以查看此过程之外的内容是否导致某种死锁情况。我通过pid查看LogCat,以查看我的流程在暂停或恢复时是否发生了任何其他情况,并且我没有看到任何异常情况。最奇怪的是,我可以一次又一次地复制精确的条件

FWIW,我已经在传递给execute方法的HttpClient实例和HttpGet实例上设置了套接字超时和连接超时。这不会导致execute方法提前返回或引发异常或诸如此类的情况。当过程“返回”时,HttpClient.execute返回一个有效的HttpResponse,所有操作都正常

我可以调试一些东西来找出哪里出错了吗?我知道这是一个非常特殊的条件,但是一般来说,有没有专门调试Android中DefaultHttpClient或http流量的高级方法?


谢谢

您是否跨线程共享同一个HttpClient?默认情况下它不是线程安全的,所以您可能需要检查它。但很可能它阻塞了I/O,所以您应该进行一些连线调试。您可以使用类似的方法来启用HttpClient wire转储日志:

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

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

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

这是我的代码,我所做的是调用
entity.consumercontent()然后就可以了。

感谢您的回复……很难找到这些具体且冗长的问题的答案。我想试试日志记录,但我相信你给我指明了正确的方向。我正在使用AsyncTask,它从线程池中为我提供线程…这可能会导致一些问题。我将尝试一个单线程派生的类,这样在不同线程上对HttpClient.execute的同时调用不会超过一个。我愿意打赌,即使在我再次运行循环之前execute返回,在下一个线程进入之前,可能还有一些清理尚未完成。顺便说一句,我添加了这段代码,在LogCat中没有看到任何其他日志。还有别的吗?是将日志转储到文件中,还是应该在LogCat中看到这一点?应该转到LogCat。确保在应用程序代码之前执行此操作,就像在静态初始值设定项中一样。我有一个自定义的应用程序类,它构建了我所有的公共对象,并将它们公开给应用程序的其余部分。我使用初始化HttpClient类的相同方法执行这些代码。我遇到了这个问题,如果我打开登录,问题就会消失。唯一的区别是我已经使用了AndroidHttpClient,它使用线程安全连接池。我怀疑是平台错误。没有真正回答这个问题。