Android平臺-實現應用增量更新

1.概述

1.1.什么是應用增量更新

當我們要更新一個應用的時候,以前很多更新的做法是下載一個新版本去覆蓋一個舊版本。隨著現在應用越來越大,我們就不得不考慮流量的問題。

Google也意識到不斷更新應用對用戶流量的損耗,于是在Google?I/O上提及了增量升級,或者叫差分升級的方法,并在新版本的Google?Play中得到支持。

簡單的來說,增量更新是指在進行更新操作時,只更新需要改變的地方,不需要更新或者已經更新過的地方則不會重復更新,增量更新與完全更新相對。

1.2.增量更新原理

增量升級的原理其實不難,我們首先使用舊版本的apk與新版本的apk做差分,就能得到更新部分的補丁,也叫差分包。這個差分包雖然不是新舊版本的簡單相減,但顯而易見的是,用戶不需要全部下載新版本apk了,我們只要下載更小的那個補丁包(差分包)。

在用戶下載完差分包后,需要在手機端將它們組合起來。一般手機的應用安裝在data/app下,我們可以復制出就版本apk至SD卡中,與下載好的差分包進行組合。最后得到一個新版本的apk后與服務器上的新版本進行校驗,正確后就可以安裝了。

2.環境搭建

2.1.NDK下載安裝

NDK(native?develop?kits),是一個交叉編譯的工具鏈。交叉編譯是指:在一個平臺下(CPU,操作系統)可以編譯出在另外一個平臺可以運行的代碼,例如我們正要做的:windows?AMD?intel?x86架構->手機android?arm處理器。

下載地址:http://www.android-doc.com/tools/sdk/ndk/index.html

2.2.Cygwin安裝

Cygwin是一個可以在windows下模擬出linux環境的一個工具,NDK必須在linux環境下進行編譯等工作。

下載地址:http://www.cygwin.com

安裝過程略。需要注意的是在Selectpackages安裝界面中把Default改為Install,直接點擊Default即可。

完成安裝后,我們啟動Cygwin,輸入make??-v命令,出現如下信息說明安裝成功了。

輸入make? -v命令

我們cd到NDK的目錄,執行./ndk-build命令,出現如下信息則說明大功告成。

執行./ndk-build命令

2.3.在Eclipse中或MyEclipse中安裝CDT插件(可選)

將下載好的安裝包解壓,把features、plugins目錄下的文件對應的復制到Eclipse(MyEclipse)中即可,重啟軟件。

3.實現過程

3.1.差分patch文件的生成

首先要生成舊版本和新版本的差分比patch文件,我們可以借助bsdiff開源庫的windows版本。我們先下載bsdiff壓縮包,解壓后有以下兩種工具。

解壓bsdiff

Bsdiff.exe就是一個二進制差分工具,bspatch.exe就是相應的補丁合成工具了。我們的增量升級的差分包,是要在服務端完成的,也就是pc端去完成。我們打開命令行,轉到bsdiff所在目錄下,將新舊版本的apk也放到該目錄下,執行命令:

bsdiff.exeoldName.apknewName.apkpatch.patch

Patch文件的名字可自己定義。如測試程序中的兩個版本的apk。

測試

3.2.patch文件放至服務器

將生成的差分包xx.patch放置到升級服務器上,供用戶下載升級。如果多版本,則必須對不同版本都進行差分。如果版本跨度太大,可以選擇整包升級。

測試中將上一步生成的Update.patch包放在發布服務器Tomcat上。

3.3.Android合成新apk

3.3.1.編寫本地方法

我們建一個Android工程,命名為UpdateDemo,用來實現應用增量更新功能。在工程中建一個包,編寫本地方法。

編寫方法

3.3.2.So文件的調用

我們首先用NDK編譯出一個*.so文件。這個文件網上有編譯好的,可以直接下載使用。附錄中詳述了如何去編譯.so文件。

將下載好的.so文件放置于3.3.1新建的工程目錄libs\armeabi文件夾下。

.so文件

我們現在就可以調用patch方法來合成新apk了。在主程序MainAcitivity類中加入以下代碼,該代碼就是調用我們所需的so庫文件。

調用so庫文件

這里得注意,我們的so文件前lib是系統生成加上去的,所以在調用中我們只需將名字去掉lib的名字作為參數。

3.3.3.配置XML

無論在下載還是合成刪除中,我們都必須獲取手機SD卡的讀寫權限,我們在UpdateDemo工程中AndroidManifest.xml加入以下代碼。

AndroidManifest.xml

3.3.4.下載patch差分包

我們在UpdateDemo工程中加上添加一個更新按鈕,實現點擊按鈕能夠彈出下載選框,點擊下載就可以下載服務器上的patch包了。我們設定下載的目錄就是SD卡的跟目錄。運行該程序,界面如圖。

apk界面

我們點擊更新按鈕,如下。

更新

3.3.5.復制舊安裝包

在合成過程中,我們需要舊安裝包。在Android中非系統程序默認安裝在data/app文件夾下,在非root情況下,我們可以對其本身安裝包進行讀操作,這樣我們就可以將它復制到SD根目錄下(和之前下載的patch文件同目錄)。

在下載完成后,下載函數返回DOWN_OVER,線程接到這個信號后,調用PatchThread()函數。

主線程

我們在PatchThread()中調用復制舊安裝包backupApplication(String?packageName,?String?dest)方法。該方法第一個參數為安裝包的ID號,如本例中的com.tutor.update,dest為復制目標路徑。該方法中,主要函數如下。

backupApplication方法

該函數能夠找到data/app下相應的安裝包。

測試中我們下載完patch文件后,立刻復制舊安裝包。

版本更新

我們用360助手查看SD中文件。

SD中文件

3.3.6.合成新apk

接下來就可以調用本地方法合成新apk了。

同樣在PatchThread()函數中,當復制成功后,我們就可以調用如下方法了。

合并apk

參數都是舊、新和patch文件的路徑。我們可以用360助手查看,新的apk已經合成,我們可以在程序中設定它的名字。這樣,我們的新apk合成成功。

新apk合成成功

3.3.7.MD5校驗

合成新apk后,我們無法預知它的正確性,在下載或在合成過程中,文件都有可能出錯,所以緊接著我們需要對它進行MD5校驗。

用MD5校驗工具對服務器上的新apk進行校驗,得到校驗碼。然后Android端合成新apk后對新apk也進行校驗。我們在UpdateDemo工程中再建一個包,編寫MD5類。

編寫MD5

我們在MainAcitivity類中的PatchThread()函數中構造MD5對象,調用check方法即可。

用返回的校驗值和服務器上的校驗值對比,相同則進行安裝,不同則提示校驗失敗。

校驗失敗

3.3.8.安裝新apk

校驗正確后自動安裝即可。緊接著校驗函數,我們加入判斷,如果校驗正確,則調用以下方法;如果錯誤,我們就跳出提示信息。

安裝新apk

安裝完成后打開軟件,已經是V2版本了,我們增量更新成功。

量更新成功

3.3.9.刪除殘余文件

最后我們只要把用戶下載的patch文件和舊apk刪除即可,用戶最終可以得到新apk,新apk用戶可以自行處理。

刪除時我們只要在安裝后或在校驗錯誤后調用delete()函數即可。

delete()函數

用助手查看SD目錄,只有新apk了。

只有新apk

如果校驗不通過,所有相關文件都會被刪除。這樣,我們就完成了我們的更新操作。

4.各種生成差分包大小列表

增量更新雖然不用將新apk的內容全部下載,但如果版本相差過大,或者apk本身非常小,還是建議下載整包。以下做了個小測試。

生成差分包大小列表

我們能夠觀察到,當apk不足1M時,差分包大小同樣也有幾百K,所以沒必要去差分。當版本相差過大,增加內容非常多時,我們也建議直接整包更新。差分時包越大耗時越長。

5.附錄

測試中我們用到網上已有的so庫,直接調用即可。我們也可以自己在客戶端生成so文件。

我們先下載bzip2-1.0.6.tar.gz。新建一個Android工程,將可能用到的下列文件復制到新建的Android工程的jni目錄下(沒有的新建一個目錄)。

下載地址:http://www.bzip.org/downloads.html。

bzip2-1.0.6.tar.gz

5.1.Android.mk配置

在該jni目錄下新建文件,命名Android.mk,配置如下。

Android.mk

5.2.方法實現

5.2.1.頭文件生成

打開cmd命令行,轉到工程目錄的bin文件夾下,輸入以下命令。

生成頭文件

系統會自動生成一個.h文件,我們把它拷貝到jni目錄下。

.h文件

5.2.2.編譯成so庫

我們在jni目錄下新建com_example_jni_MainActivity.c,完成c代碼。

com_example_jni_MainActivity.c

打開Cygwin,轉到工程目錄,使用ndk命令編譯成so庫即可。

編譯成so庫

我們可以看到libBSdiff.so已經編譯成功,在lib/armeabi目錄下。

libBSdiff.so

這樣,我們就可以使用該so文件去合成新apk了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容

  • 在前幾年,整體移動網絡環境相比現在差很多,加之流量費用又相對較高,因此每當我們發布新版本的時候,一些用戶升級并不是...
    涅槃1992閱讀 5,507評論 2 39
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,665評論 25 708
  • @[增量更新,差分包,bsdiff/patch] 背景 隨著Android app的不斷迭代升級,功能越來越多,a...
    SunYo閱讀 14,900評論 2 7
  • 經艷子姐介紹加入組織后,真真切切感受到筆友們對文字的喜愛,對寫作的熱情,不同年齡,不同職業,天南海北的人聚在一起,...
    半山桃源閱讀 191評論 5 4
  • 為什么在一起 兩個人選擇在一起,可以是因為熱戀的愛情,也可以不是因為難以自拔的愛。 試想,你...
    青糯君閱讀 631評論 0 3