天天看點

Android Asynchronous HTTPClient的實作和優化

大家知道android對ui線程的反應時間要求很高,超過5秒鐘直接anr掉,根本不給你機會多等。

而android應用與後端系統的互動是最基本的需求之一,如何實作高效的asynchronous httpclient,確定ui線程在啟動任務後交由後端異步處理與伺服器端的通信,尤為關鍵。

google過幾個方案,要麼太複雜要麼不符合要求,基本都淘汰了,最後發現這一版本的實作不錯,就拿來用了。

連結:android asynchronous httpclient tutorial

後來發現了幾個嚴重的問題,羅列如下:

1. 啟用單獨的線程後,簡直如脫缰的野馬,難以駕馭。

現象是:在調試的時候經常發現某個線程死掉(比如在伺服器down掉的時候,由于線程無法連接配接而挂掉)

後果是:隻能關掉模拟器,甚至還要重新開機eclipse,否者兩者通信出現問題,再也不能繼續聯機調試

2. 異常的處理非常弱,activity層難以捕捉并加以處理。

這個問題跟實作的機制有一定的關系,此實作根本就沒提供好的異常處理機制,以便捕捉、回報、處理合理的可預見性的異常,諸如:

1)unknownhostexception – 誰能確定手機的網絡連接配接一直正常,信号一直滿格?

2)httpresponseexception – 後端500的錯誤,說不定就蹦出來了

3)sockettimeoutexception – 逾時也是太正常不過了,如果人家在荒山野嶺(no 3g)擺弄超大的通信請求

4)諸如此類吧

是以改造就再說難免了。下面我貼出相關代碼(import就省了吧這裡),并加以簡單注釋說明,方面大家的了解。

首先定義asynchttpclient.java。這裡的重點是逾時的設定。另外我加了個cancelrequest,用以在切換activity後取消掉原有activity發出的所有的異步請求,因為一般情況下,切換了activity後是不能再更新那個ui了,否則會抛出異常,直接導緻應用crash掉,不過話說回來,這個cancel我發現好像不是那麼給力(any feedback?)。

然後是asynchttpsender。這裡我用了inputholder和outputholder來進行對象傳遞,簡單包裝了下:

再來看看我們的call back接口定義, asyncresponselistener.java:

以及抽象call back的實作,abstractasyncresponselistener.java:

這樣我們使用起來就非常清晰、簡單了。

下面貼個簡單的用戶端用法代碼片段:

1、這個是把伺服器端響應當stream用的,用以諸如檔案、圖檔下載下傳之類的場景:

2、這個是把伺服器端響應當json用的,用以諸如擷取基本文本資訊之類的場景: