**在前面:好長(zhǎng)時(shí)間沒(méi)寫東西了 呵呵,這篇文章是基于Mac系統(tǒng),Window估計(jì)思路差不多**。(>_<)!??!
背景:
現(xiàn)在移動(dòng)應(yīng)用市場(chǎng)APP隨著的需求的增加包體積也在不斷的增大,以及應(yīng)用版本不斷的發(fā)布,按照通暢做法,APP升級(jí)會(huì)需要很多的流量,而且還慢,這種情況下用戶體驗(yàn)需要提高,需要找到一種輕量升級(jí)方案。在Google I/O 上提及的 Smart App update,即應(yīng)用增量升級(jí),或者叫做差分升級(jí)的做法,并在新版的Google Play以及國(guó)內(nèi)各大應(yīng)用分發(fā)平臺(tái)已經(jīng)可以很好的做到這點(diǎn)。目前我們也計(jì)劃采用增量的方式升級(jí)應(yīng)用。
**增量升級(jí)的原理**:
- 先生成新版本與舊版本之間的差分包
- 手機(jī)Client端獲取相對(duì)應(yīng)版本的差分包,舊版本的APK與差分包,合成一個(gè)新的APK
- 校驗(yàn)新合成的微博客戶端文件是否完成,簽名時(shí)候和已安裝客戶端一致,如一直,提示用戶安裝
- 新的APK一般放在SD卡上,安裝完成后從SD卡刪除,這些都是由系統(tǒng)自動(dòng)處理
**OK,Let’s GO**…..
- 差分(新版APK與舊版APK)
差分(Diff)工具使用的是bsdiff,這個(gè)工具可以通過(guò)MAC Terminal cmd: which bsdiff查看是否安裝,有的貌似已經(jīng)自帶了, 使用的方法 ? ?bsdiff ?oldFilePath newFilePath patchFilePath
- 合成 ?(將下載到的差分包和舊版APK合成成新的APK)
合成工具是bspatch, 這個(gè)mac 貌似也已經(jīng)默認(rèn)安裝了,同樣可以通過(guò)上面的方法查看
- NDK編譯獲取到.so文件;注意這里是坑&坑的聚集地,首先配置NDK編譯環(huán)境
(1)從Android Studio 1.3 Beta1開始,就支持了NDK。不過(guò)需要使用的是一個(gè)全新的實(shí)驗(yàn)性的gradle構(gòu)建工具(繼續(xù)往下看有介紹)。官方地址http://tools.android.com/tech-docs/new-build-system/gradle-experimental,英文好的可以直接看原文
目前使用的最新的是Android Studio2.0版本

(2)使用Android Studio內(nèi)置的SDK管理器下載NDK

(3)然后:點(diǎn)擊File -> Project Structure ->出現(xiàn)下圖為Android NDK選擇路徑

(4)接下來(lái)要修改的被標(biāo)紅的文件如下三個(gè):

app Moudle內(nèi)的build.grade 修改:
- com.android.application 改為 com.android.model.application
- 原來(lái)的基礎(chǔ)上加一個(gè)model{}
- 鍵值對(duì)(Key - Value)都要用”=“號(hào)
- defaultConfig 改為 defaultConfig.with
- 添加compileOption.with{},以及相應(yīng)的編譯環(huán)境
- buildTypes 修改為 android.buildTypes{}
- 添加android.ndk{},以及里面的相應(yīng)配置
最后就是這個(gè)樣子

(5)并且需要gradle 2.5的支持,將gradle/gradle-wrapper.properties中的版本修改為2.5
distributionUrl=https\\\\\\\\://services.gradle.org/distributions/gradle-2.5-all.zip

(6)首先需要將根目錄下的gradle修改為實(shí)驗(yàn)性的gradle
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
最終是這樣的

(7)在android.ndk中進(jìn)行ndk的配置,模塊名字是必須的,并且支持armeabi,armeabi-v7a,x86三個(gè)平臺(tái)。
然后增加jni目錄,在main上右鍵新建jni目錄

(8)接下來(lái)創(chuàng)建一個(gè)工具類:

(9)繼續(xù)點(diǎn)開AS的Terminal標(biāo)簽,默認(rèn)進(jìn)入到該項(xiàng)目的app文件夾下。我在windows平臺(tái)下輸入如下命令跳轉(zhuǎn)到class中間文件生成路徑:
xxxxx\\\\\\\\app> cd build\\\\\\\\intermediates\\\\\\\\classes\\\\\\\\debug
然后執(zhí)行如下javah命令生成h文件。
xxxxx\\\\\\\\debug> javah -jni 包名+類名(例如:PathUtils)
執(zhí)行完之后你可以在文件夾app\\\\\\\\build\\\\\\\\intermediates\\\\\\\\classes\\\\\\\\debug下看見生成的 .h頭文件為:
包名+類名(例如:PathUtils).h
(10)在得到.h文件后在創(chuàng)建一個(gè).c文件,最后是這樣

(11)編譯后的.so文件在哪 ,在app/build/intermediates/binaries/debug/目錄下
(12)編譯好的.so文件用到其他地方時(shí)保證包名和編譯時(shí)的包名一致
(13)注意全程并沒(méi)有用到Android.mk文件
**抽空把demo分享出來(lái)** )>_<(
常見的異常如下,請(qǐng)對(duì)號(hào)入座:
1.所有值的設(shè)置都要寫成 xxx = yyyy的形式,比如: applicationId = "com.zyp.ndktest" (自動(dòng)生成的gradle 則可能是: applicationId = "com.zyp.ndktest" ?),否則會(huì)爆這種錯(cuò)誤:Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject, 當(dāng)出現(xiàn)此類錯(cuò)誤,檢查是否都用了 “=”的方式。
2. buildTypes 需要從android{} 中取出來(lái),寫成android.buildTypes{}的形式,否則會(huì)出現(xiàn)這種錯(cuò)誤:Error:Unable to load class 'org.gradle.nativeplatform.internal.DefaultBuildType_Decorated'.
3.此外,自動(dòng)生成的buildTypes的形式和上面的也不一樣為以下的形式:
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), ? ? ? ? ? ? ? ?'proguard-rules.pro'
}
需要改成上面文件中的格式,否則會(huì)報(bào)這種錯(cuò)誤:Error:No signature of method: org.gradle.model.ModelMap.minifyEnabled() is applicable for argument types: (java.lang.Boolean) values: [false]
4.defaultConfig{} 需要寫成defaultConfig.with{} 的形式,否則會(huì)報(bào)這種錯(cuò)誤:Error:Cause: com.android.build.gradle.managed.AndroidConfig_Impl
5. 在defaultConfig.with{} 中 需要寫成
minSdkVersion.apiLevel ?= 19
targetSdkVersion.apiLevel = 23
也就是比自動(dòng)生成的多 .apiLevel ,否則會(huì)報(bào)這種錯(cuò)誤:Unable to load class com.android.build.gradle.managed.ProductFlavor_Impl
6. 增加compileOptions.with{} 需要選擇JavaVersion.VERSION_1_7,否則會(huì)報(bào)這種錯(cuò)誤:Bad class file magic or version
2016/03/23下午于北京,天氣很好
轉(zhuǎn)載請(qǐng)注明鏈接:謝謝)>_<( ? ?