Android應用分發器實現-適合團隊迭代開發和測試
近期開發 Android TV 平臺應用,編譯後通過 adb tcpip 埠推送到 TV 或盒子上的上傳速率簡直分分鐘讓人抓狂。這樣開發的效率極低,尤其是適配那些老舊的盒子,一次推送十幾分鍾都是正常的,分分鐘血壓180。怎樣才能減少這個時間呢?實際上這些裝置在觀看視訊是並不慢,這就說明下載速度是正常的。這樣我們可以通過下載的方式將我們的應用下載並安裝到裝置中,具體實現就是後面要寫的”應用分發器“了。
應用分發器潛在的使用者
如果是簡單寫一個apk下載安裝器似乎沒啥太大的意義,既然寫了,不妨完善一下它的功能。哪些人會使用分發器呢?
- 開發人員:
正如上面我遇到的問題,TV推送效率極低,使用分發器可以將應用編譯打包後,通過下載的方式安裝到裝置中,提高開發效率。如過不需要除錯的話,可以實現不連線裝置的情況下檢視開發效果。如果需要除錯,就必須連結裝置了,啟動除錯可以通過adb shell am -d 命令以除錯的方式啟動應用。 - 測試人員:
一個應用的開發往往伴隨著開發團隊和測試團隊的配合。開發人員釋出應用,通過某種方式傳送給測試人員,測試人員需要連線裝置或者其他通訊工具傳送到裝置進行安裝測試。這個過程同樣十分耗時。而且到真正發版前,這個過程往往需要多次的迭代,十分痛苦。應用分發器可以極大的簡化這個流程,去除很多重複勞動!開人員只需釋出應用,然後開發人員便可以直接在安裝過分發器的裝置上安裝測試! - 普通使用者:
設計分發器的初衷是給團隊開發測試使用的,但同樣可以用於給普通使用者分發應用。比如內測使用者,或者一些無法正常上架應用市場的應用。
應用分發器功能分析:
分發包括四個部分:
- 分發器主動獲取釋出者有哪些可用的應用
- 釋出者主動推送應用到各個裝置
- 可以動態設定釋出者
- 應用下載安裝
分發器主動獲取釋出者有哪些可用的應用:
這種主動獲取的方式實現起來比較簡單,只需在分發器啟動和使用者主動點選時獲取可用列表既可以
釋出者主動推送應用到各個裝置:
這種分發機制實現有一定困難,首先是應用”保活“,然後使用心跳方式獲取釋出至”推送“的應用
可以動態設定釋出者:
每個使用分發器的團隊的釋出者都是不同的,所以應當可以動態設定釋出者。這裡所說的釋出者,實際就是儲存應用資訊的伺服器地址或者網盤地址
應用下載安裝
這個功能沒啥可解釋的,幹活吧!
實現技術分析
- 首先得儲存應用資訊:應用資訊可以儲存在Json裡,具體結構,在後面具體功能實現中詳細分析。然後把JSON放到可一個可以下載的地方就可以了。可以自己建立一個小伺服器或者直接使用網盤地址。百度網盤地址不穩定,而且下載很慢。可以自己使用nextcloud 搭建一個。nextcloud 可以保持檔案下載地址不變的情況下,更新檔案。上傳也有簡單的api可用,寫個20行左右的Python指令碼就可以,如果有想用可以留言討論下。
- 獲取應用列表,展示應用資訊,獲取推送通知,下載安裝這幾個功能沒有太大的技術障礙。
- 推送:這個實現比較困難,這也是Android的一大痛點。要實現推送,首先是應用保活,實現方式有很多,但大多有缺陷,擇優選擇一種實現。其次是開機啟動,在高版本的系統實現起來比較麻煩。
- 動態配置釋出者:這個可以通過分發器端的設定裡動態設定。
功能實現
分發器我已經寫了一段時間了,目前功能已經基本實現。
- 可用應用列表和推送資訊通過兩個JSON儲存:
{ "flag": 1, "pkg": "com.jepack.dispatcher", "url": "http://192.168.31.92/dispatcher.apk", "md5": "91377cf93d7c510f745d2a7192602245", "app_code": 1, "force": true, "title": "APK Dispatcher 0.1.0", "desc": "Function done!" }
[ { "url": "http://192.168.1.217/cache.apk", "md5": "fe4aa390ba7fb86fa05256bd2bd8d1a2", "title": "應用1-修復xx", "desc": "" }, { "url": "http://192.168.1.217/cache1.apk", "md5": "fe4aa390ba7fb86fa05256bd2bd8d1a2" } ]
-
分發器客戶端實現
如下圖,
- 工程使用了 DaemonService 做應用保活。
- receiver 是開機啟動的 receiver;
- service包含保活的service,其中通過心跳的方式獲取推送內容並作出相應操作;settings包含動態修改釋出者等的設定;
- Activity包含應用列表的顯示及對應操作;
- AppUtil實現了應用的通知、下載、安裝等操作。
- fi.iki.elonen 為在手機裡建立的區域網伺服器,不想在手機裡輸入釋出者地址可痛苦區域網api實習修改,具體參見工程README

工程結構
-
下圖是設定頁面:
設定頁面
-
具體功能程式碼
原始碼已釋出到我的 Github 。
下載功能用到了Rxjava/RxAndroid,其中的filter功能最近開始使用。如果大家同意使用Rxjava/RxAndroid,可以試試,非常實用。有其他使用新得也歡迎大家一起討論!工程中大部分程式碼使用kotlin語言編寫,有不足之處還請指正!
downloadDisposable = downloadSubject.observeOn(Schedulers.io()).filter { it.action in arrayOf(ACTION.ACTION_PAUSE, ACTION.ACTION_START, ACTION.ACTION_STOP, ACTION.ACTION_CONTINUE) }.subscribe( {dlMsg-> when(dlMsg.action){ ... } }, {})
- 已實現功能:
- 固定應用列表獲取並顯示
- 簡單的應用保活
- 推送機制
- 動態配置釋出者
- 應用下載(可設定MD5校驗策略,建議穩定的區域網可不校驗)、通知、安裝
- 手動輸入一個特殊地址安裝
- 簡單的開機啟動實現(未測試)
目前功能已經基本可以使用了(我自己的團隊也正在用,如果配合Gradle 外掛、Jenkins持續交付機制就更完美了),歡迎使用和留言探討!