2011-08-17 61 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

沒有真正回答這個問題。 –

相關問題