天天看點

android網絡業務的封裝與排程

http://ikeepu.com/bar/10266838

手機用戶端程式由于網絡寬帶的限制,尤其在gprs網絡環境下,大資料量的網絡互動很大程度上降低應用的響應,影響使用者體驗。比如,如果做一個手機網盤用戶端,在背景上傳檔案時(大資料量的互動),擷取檔案清單(指令類的互動)這個過程就顯得太别慢。而我們的要求是希望這些指令類操作能盡快得到響應。

通常,在手機用戶端,我們設計一個網絡操作的管理器,來統一管理這些需要聯網的操作。

具體做法是把網絡操作封裝成一個command(或者說是task),管理器實作特定的排程規則來排程運作這些task。

這樣做的好處至少有三:

一. 用command封裝了網絡操作,使得這些操作與上傳的業務分離,解除了強耦合。

二. 可以根據網絡情況來确定來采用不同的排程規則,提高使用者體驗。

三. 重用,這些task和taskmanager的代碼在别的手機應用上基本上能照搬過去。

四. 擴充,當應用需要擴充新的業務時,隻有擴充一個新的command(或者說是task),接受排程即可,易于擴充。

例子:

還是以上文提到的微盤為例,可以概括我們對管理器的設計要求有:

在wifi網絡環境下:

一:各種網絡操作可以并行運作。

在gprs網絡環境下:

二:支援優先級搶占排程,指令類操作的優先級比資料傳輸類的優先級高,當指令類的task(擷取檔案清單)送出後,打斷資料傳輸的task(如上傳,下載下傳),等指令類的任務運作完畢,再接着運作資料類任務(斷點上傳,下載下傳)。

二:同一個優先級的任務可以并行運作,如多個指令一起在網絡上傳輸。

實作思路:

taskmanager :

1. taskmanager開辟一個背景線程進行排程工作。

2. 由于要支援多個優先級的搶占排程,我們需要兩個隊列來維護運作中的task和等待中的task。

3. 由于task的排程是基于優先級的,我們可以使用優先級隊列,運作隊列采用priorityqueue,等待隊列使用priorityblockingqueue,當沒有網絡業務需要運作時,排程線程阻塞挂起,避免空轉。

4. taskmanager設計為單一執行個體(單一模式)。

5. 每個task被排程運作時,該task被從等待隊列移動運作隊列,當task執行完畢時,從運作隊列删除,喚醒排程線程進行新的排程。

下面是簡單的設計代碼:

task:

1. 對要執行的網絡操作的封裝。

2. task執行完畢時,發task結束信号,喚醒排程線程進行新的排程

3. task要實作comparable接口,才能讓taskmanager的兩個隊列自動其包含的task排序。

小注意事項:

android對priorityqueue的實作和jdk中的實作有點不一樣。

(priorityqueue.java在android中的代碼路徑是usr\dalvik\libcore\luni\src\main\java\java\util)

priorityqueue.remove(object o) ;//從priorityqueue中删除一個元素。

對于完成這個删除操作android和jdk都是分兩個過程實作,一,找出待删除元素的索引index,二,删除index所在元素。

在jdk中,是通過調用元素的equals方法來找到待删除元素的索引,

在android中,是間接調用元素的compareto方法判斷結果是否為0來找到待删除元素的索引,

是以為了task能在執行完畢時從priorityqueue找到這個task并删除之,需要在compareto方法裡在優先級相等時傳回0。

當是這樣運作priorityqueue.remove(object o) 邏輯上隻能删除priorityqueue裡第一個優先級與被删除的元素優先級相等的元素(可能是待删除的元素也可能不是),有誤删的可能,需要做如下修改:

這樣才能正确執行remove(object o),删除指定的對象o。

個人覺得android這樣設計使得remove(object o)複雜化了,不然jdk中那麼簡潔。語義上也不是那麼好懂了,

因為按通常了解,equals是判斷兩個對象是否相等,compareto可能是對象的某個屬性的比較(類别資料庫中的order by),

而現在執行priorityqueue.remove(object o),這個對象o明明在容器priorityqueue中,卻删除不了,除非去翻看android中priorityqueue的實作代碼,然後重寫compareto這個方法。這樣的api使用時比較容易出錯,應該不符号良好的api設計規範

吧。

完整的代碼實作如下:

拾漏補遺:

1.補充最初的設計類圖(可能與代碼不太一緻,但能說明問題)

android網絡業務的封裝與排程

2. businessobject的實作代碼: