Android 增量更新實例(Smart App Updates)

自從 Android 4.1 開始,Google引入了應用程序的增量更新。 java

  • 官方說明android

Smart app updates is a new feature of Google Play that introduces a better way of delivering app updates to devices. When developers publish an update, Google Play now delivers only the bits that have changed to devices, rather than the entire APK. This makes the updates much lighter-weight in most cases, so they are faster to download, save the device’s battery, and conserve bandwidth usage on users’ mobile data plan. On average, a smart app update is about 1/3 the sizeof a full APK update.

 http://developer.android.com/about/versions/jelly-bean.htmlgit

  • 實現原理github

增量更新的原理很是簡單,就是將本地apk與服務器端最新版本比對,並獲得差別包,用戶更新App時只須要下載差別包。例如,當前安裝新浪微博V3.5,12.8 MB,新浪微博最新版V4.0,15.4MB,通過對兩個版本比較以後,發現差別只有七、8M,這時候用戶更新的時候只須要下載一個七、8M的差別包即可,不須要整包下載15.4M的新版微博客戶端。下載差別包後,在手機端使用舊版apk+差別包,合成獲得微博最新版V4.0,提醒用戶安裝便可。 

服務器

  • 實現app

以新浪微博客戶端的升級爲例,假設手機上安裝的是V3.5,如今最新版是V4.0,用戶須要從V3.5升級到V4.0。 

弄清楚原理以後,咱們就須要解決兩個問題: 
1.如何比對兩個版本的apk生成差別包; 
2.如何使用舊的apk+差別包,生成一個新apk; 

工具

(1)生成差別包


這一步須要在服務器端來實現,通常來講,apk有新版本以後,須要日後臺管理端上傳新apk,上傳時就應該生成每個舊版與最新版本的差別包。 
假設,你的apk已經發布了3個版,1.0,2.0,3.0,這時候你要在後臺發佈4.0,在你上傳時,就應該生成 
1.0——>4.0的差別包; 
2.0——>4.0的差別包; 
3.0——>4.0的差別包; 

選擇使用這個開源二進制比較工具來實現: 
http://www.daemonology.net/bsdiff/ 
下載後獲得bsdiff-4.3.tar.gz。 

其中bsdiff.c是二進制文件比對的代碼;bspatch.c是二進制文件合成的代碼; 
咱們將使用這個bsdiff來生成兩個apk的patch包,而且使用bspatch.c來合成舊apk與patch包; 

使用bsdiff、bspatch時,還需用到bzip2: http://www.bzip.org/downloads.html  
下載後獲得:bzip2-1.0.6.tar.gz。 
咱們須要用到bzip2-1.0.6.tar.gz中如下13個文件(這裏面可能有的是不須要的,我都拷貝過來了): 
測試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
blocksort.c 
bzip2.c 
bzip2recover.c 
bzlib_private.h 
bzlib.c 
bzlib.h 
compress.c 
crctable.c 
decompress.c 
dlltest.c 
huffman.c 
randtable.c 
spewG.c

將這13個文件拷貝至jni目錄下,接下來,咱們就調用bsdiff生成差別包,而且調用bspatch合成新包。 

我是在Mac下作的,使用java開發,經過jni調用C程序(bsdiff、bzip2)。 

調用,com.cundong.utils.DiffUtils.java中genDiff()方法,能夠經過傳入的新(newApkPath)舊(oldApkPath)apk,獲得差別包(patchPath)。 
spa

?
1
public  static  native  int  genDiff(String oldApkPath, String newApkPath,String patchPath);

調用,com.cundong.utils.PatchUtils.java中patch()方法,能夠經過舊apk(oldApkPath)與差別包(patchPath),獲得新apk(newApkPath)。

?
1
public  static  native  int  patch(String oldApkPath, String newApkPath,String patchPath);

(2)使用舊apk+差別包,在客戶端合成新apk


差別包已經在服務器端生成,咱們只須要在客戶端提示用戶有更新,而後讓用戶來下載差別包,下載成功以後, 
使用本地apk與差別包,生成新版apk。 

這一步須要在Android應用中開發。 
1.首先NDK編譯出一個*.so,APKPatch工程負責生成 libapkpatch so,生成的so文件位於APKPatch/libs/libapkpatch.so下,其餘Android工程即可以使用該so文件來合成apk。 

2.調用該so文件。 
任意一個Android工程,使用該so文件,拷貝至libs\armeabi中,即可以調用patch()方法,來和成舊apk+差別包。 
附件中,test工程,就是一個調用該so文件的例子。 

  • 注意事項

1.新包和成以後,還須要對合成升級版本的apk包及最新版本apk包進行MD5或SHA1校驗,若是校驗碼不一致,說明合成過程有問題,新合成的包將不能被安裝。 

2.增量升級成功的前提是,用戶手機端必須有可以讓你拷貝出來且與你服務器用於差分的版本一致的apk,這樣就存在,例如,系統內置的apk沒法獲取到,沒法進行增量升級;對於某些與你差分版本一致,可是內容有過修改的(好比破解版apk),這樣也是沒法進行增量升級的,爲了防止合成補丁錯誤,最好在補丁合成前對舊版本的apk進行校驗,保證基礎包的一致性。 

  • demo

demo中,包含如下文件: 

1.服務器端生成差別包的工程:AppUpdate; 

2.客戶端編譯獲得so的工程:APKPatch; 

3.調用so文件,實現增量更新的工程:test;

4.兩個用於測試的微博apk;

下載 

by  @Cundong

相關文章
相關標籤/搜索