HttpClient останавливается на длительные периоды времени, даже с установленными параметрами тайм-аута - PullRequest
5 голосов
/ 17 августа 2011

У меня есть приложение, которое выполняет нетривиальную загрузку миниатюрных изображений и других ресурсов из удаленной службы.

Я использую один экземпляр DefaultHttpClient и пользовательский класс, который я написал, который планирует все мои загрузки. Все загрузки выполняются последовательно в фоновых потоках через AsyncTask. Я не запускаю процедуру загрузки до тех пор, пока в AsyncTask не будет запущено onPostExecute.

Это часто работает отлично. Если я поставлю в очередь 20 изображений, мой планировщик справится со своими задачами. Однако я сталкиваюсь со случаями, когда процедура просто останавливается в точке вызова client.execute (где client - это мой экземпляр DefaultHttpClient). Я могу необъяснимым образом реанимировать этот процесс, перемещаясь по приложению и выполняя случайные действия (прокрутка списка, перемещение назад и вперед между действиями и т. Д.). Как будто что-то, что я делаю, посылает сообщение "проснуться" потоку, который остановился или заблокирован.

Я добавил несносное количество журналов во все движущиеся части моего приложения, чтобы посмотреть, не вызывает ли что-то внешнее этой процедуры какое-либо состояние тупика. Я просматриваю LogCat по pid, чтобы увидеть, происходит ли что-то еще в моем процессе в момент остановки или возобновления, и я не вижу ничего необычного. Самое странное в этом то, что я могу повторять точное условие снова и снова.

FWIW, я установил таймауты сокетов и тайм-ауты соединения как для экземпляра HttpClient, так и для экземпляра HttpGet, который я передаю методу execute. Это не приводит к тому, что метод execute возвращает рано или выбрасывает исключение или что-либо подобное. Когда процедура «возвращается обратно», HttpClient.execute возвращает допустимый HttpResponse, и все работает как обычно.

Любые идеи о том, что я могу отладить, чтобы выяснить, где это происходит? Я признаю, что это очень специфическое условие, но Существуют ли какие-либо продвинутые методы для специальной отладки трафика DefaultHttpClient или http в Android в целом?

спасибо!

Ответы [ 2 ]

5 голосов
/ 17 августа 2011

Разделяете ли вы один и тот же HttpClient между потоками? По умолчанию это не потокобезопасно, так что вы можете проверить это. Скорее всего, это блокирует ввод-вывод, поэтому вам следует выполнить некоторую отладку проводов. Вы можете использовать что-то вроде этого для включения журналов дампа проводов 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");

Чтобы включить его, выполните следующие команды оболочки. Журналы проводов будут выводиться в 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 голосов
/ 22 сентября 2011

У меня раньше была похожая проблема.Когда я пытаюсь получить HTTP, попадающий в очередь, метод httpClient.execute(get); не будет возвращать ответ, например, тупик.

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

Это мой код, и я вызываю entity.consumeContent();, затемработы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...