天天看點

Android 應用增量更新方案之實踐篇

作者:snowdream email:yanghui1986527#gmail.com qq 群: 529327615

每次下載下傳完整的新安裝包,進行覆寫安裝。

将新安裝包和已經安裝的舊安裝包進行比對,生成一個差分更新包(patch包)。使用者下載下傳patch包後,和已經安裝的舊安裝包進行合并,生成新安裝包,再進行覆寫安裝。

在早期的android應用開發中,由于android應用普遍比較小,是以,普遍采用了全量更新方案。簡單粗暴,卻行之有效。

但是,随着android的發展,android應用功能越來越多,體積越來越大,再綜合以下幾個因素考慮,全量更新方案逐漸無法滿足我們的需求。

1.在國内,随着2g,3g,4g的逐漸演進,手機網絡越來越快,但有一點事實仍然沒有改變:流量很貴,非常不夠用。(這個因素不适合wifi使用者和土豪使用者)

Android 應用增量更新方案之實踐篇

以北京移動為例,最基礎套餐,5元30m流量。而最新的微信apk安裝包35m。也就是說,如果你選了最基礎套餐,你一個月内使用全量更新方案,更新一次微信,流量都不夠用。

2.在靈活開發大行其道的今天,開發者希望盡快将新開發的功能推送到使用者面前,并及時得到使用者的回報。恨不能三天一小版,一周一大版。

綜合以上因素,開發者必須為使用者考慮:省流量,省流量,省流量。

顯然,全量更新這種土豪做法已經不再适用,于是,增量更新應運而生。

首先,兩句話簡單概括增量更新原理:

1.服務端通過比對最新更新包,和目前應用包,生成差分更新包;

2.用戶端将差分更新包和目前應用包合并,生成最新更新包。

接下來,簡單介紹下增量更新的原理:

1.首先,用戶端擷取目前應用的version code和應用apk檔案的md5值,發送給伺服器;

2.伺服器根據既定政策,給使用者傳回更新包資訊。

通過md5值沒有查詢到舊有apk應用資訊,傳回全量更新包網址,全量更新包md5值;

需要傳回patch包,但還沒有生成patch包時,背景去生成patch包,并傳回全量更新包網址,全量更新包md5值;

需要傳回patch包,并且已經生成patch包時,傳回patch包網址,patch包md5值,全量更新包網址,全量更新包md5值;

不需要傳回patch包,則傳回全量更新包網址,全量更新包md5值;

3.用戶端根據傳回資訊進行更新操作。

如果隻有全量更新包相關資訊,則下載下傳全量更新包,并在校驗md5值後,安裝更新包;

如果有差分更新包(patch包),則下載下傳差分更新包。校驗差分更新包的md5值。如果校驗失敗,走上面一個步驟。如果校驗成功,則将差分更新包和目前版本的apk進行合并操作,生成新的應用包。校驗新的應用包md5值。校驗通過,這安裝這個生成的新應用包。如果校驗失敗,則走上面一個步驟。

以上隻是簡單介紹了增量更新的原理,實際應用中還需要細化,考慮更多的場景。

注意: 下載下傳過程中,必須支援斷點續傳政策。防止網絡不暢時,不斷重試,造成的流量浪費。

增量更新方案的核心就是使用diff/patch算法來對新舊apk進行diff/patch操作。

在封裝hdiffpatch過程中遇到問題,得到作者@sisong的支援和幫助,在此表示感謝。

bsdiff/bspatch和hdiffpatch算法都是開源的,服務端可以根據源檔案來進行編譯內建。

這裡我主要在android用戶端的角度,介紹下bsdiff/bspatch和hdiffpatch怎麼使用。

在build.gradle檔案中自定義jnilib目錄

将 <code>app/libs/armeabi-v7a/libbsdiffpatch.so</code> 拷貝到你的工程對應目錄下。

将 <code>app/src/main/java/com/github/snowdream/bsdiffpatch</code> 和 <code>app/src/main/java/com/github/snowdream/diffpatch</code> 拷貝到你的工程對應目錄下,包名和檔案名都不能改變。

在java檔案中參考以下代碼進行調用。

将 <code>app/libs/armeabi-v7a/libhdiffpatch.so</code> 拷貝到你的工程對應目錄下。

将<code>app/src/main/java/com/github/snowdream/hdiffpatch</code> 和 <code>app/src/main/java/com/github/snowdream/diffpatch</code> 拷貝到你的工程對應目錄下,包名和檔案名都不能改變。

這裡我選擇高德地圖android用戶端的兩個版本來進行測試。

測試版本: amap_android_v7.7.4.2128_guanwang.apk 和 amap_android_v7.3.0.2036_guanwang.apk (注:版本跨度大,差異大)

對比算法: bsdiffpatch vs hdiffpatch

測試結果:(詳見下圖)

bsdiffpatch生成的patch包稍小。

兩者的diff操作都非常耗資源,耗時間,無法忍受。(當然diff操作一般在服務端進行)

兩者的patch操作都比較快。通過大概五次測試,bsdiffpatch的patch操作需要13s左右,而hdiffpatch的patch操作僅僅需要1s左右。

以上結果僅供參考。

測試結論:

bsdiffpatch應用更廣泛

hdiffpatch看起來更高效

Android 應用增量更新方案之實踐篇

以上算是比較成熟的增量更新方案了,但是仔細想想,可能還存在一些問題:

1.由于多管道,多版本造成非常多patch包

2.bs diff/patch算法性能和記憶體開銷太高

第一個問題可以通過伺服器政策進行限制。比如,隻有最新版5個版本内的更新采用增量更新,其他的仍然采用全量更新。

據說,還有一種更強大的算法,可以解決以上問題。大家有興趣的話,可以自己去了解。

<a href="https://gist.github.com/9468305/fa8f1307ea4738225fca">crsync-基于rsync rolling算法的檔案增量更新.md</a>

<a href="http://bbs.umeng.com/thread-19-1-1.html">友盟增量更新的原理是什麼</a>

<a href="http://my.oschina.net/liucundong/blog/160436">android應用增量更新庫(smart app updates)</a>

<a href="http://blog.csdn.net/yyh352091626/article/details/50579859">android實作應用的增量更新更新</a>

<a href="https://github.com/smuyyh/incrementallyupdate">https://github.com/smuyyh/incrementallyupdate</a>

<a href="http://blog.csdn.net/hmg25/article/details/8100896">淺析android應用增量更新</a>

<a href="https://github.com/cundong/smartappupdates">https://github.com/cundong/smartappupdates</a>

<a href="https://github.com/sisong/hdiffpatch">https://github.com/sisong/hdiffpatch</a>

<a href="http://www.daemonology.net/bsdiff/">http://www.daemonology.net/bsdiff/</a>

<a href="https://github.com/snowdream/android-diffpatch">https://github.com/snowdream/android-diffpatch</a>