Nawa Android熱補丁
案例使用:
1,運行samle顯示『hello world』.
2,複製 sample/build/outputs/nuwa 目錄保存到一個文件夾下.
3,修改Hello.java中方法返回的字符串。
4,用命令行 ./gradlew clean nuwaQihooDebugPatch -P NuwaDir= 保存的文件夾目錄,生成path.jar
5,用命令行 adb push sample/build/outputs/nuwa/qihoo/debug/patch.jar /sdcard/ 將新打出來的patch.jar複製到app存儲中。
6,重啓app就可以看到熱更新的內容。
集成:
1,添加gradle依賴到根目錄的 build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'cn.jiajixin.nuwa:gradle:1.2.2'
}
2, 添加gradle依賴到項目下的 build.gralde (使用該sdk)
apply plugin: "cn.jiajixin.nuwa"
dependencies {
compile 'cn.jiajixin.nuwa:nuwa:1.0.0'
}
3,在application中使用
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Nuwa.init(this);
Nuwa.loadPatch(this,patchFile)
}
4,混淆文件中加入
-keep class cn.jiajixin.nuwa.** { *; }
特性:
1,動態加載補丁dex,並將補丁dex插入到dexElements最前面
2,需要熱更新的類要防止被打上ISPREVERIFIED標記
代碼步驟:
1,Nuwa預先將Hack.class這個類(空實現)打成apk文件,
放在asserts目錄中,在init方法中,做的就是將asserts目錄中的這個文件拷貝到文件目錄下。
2,調用loadPatch方法將該apk動態加載進來。loadPatch方法也是之後進行熱修復的關鍵方法
3,loadPatch方法中主要是調用DexUtils.injectDexAtFirst()方法將dex插入到dexElements最前面。該方法如下。
4,根據傳入的dex的文件目錄defaultDexOptPath,構造DexClassLoader對象dexClassLoader,然後通過getDexElements方法獲得原來的dexElements對象,之後拿到dexClassLoader對象中的dexElements對象,調用combineArray方法將這兩個對象進行結合
github地址: https://github.com/jasonross/Nuwa
=================
附錄:近兩年Nuwa已經不更新了,Gradle插件支持還保留在1.5,下面有個可用版本的Nuwa(原理和Nuwa一樣): https://github.com/dodola/RocooFix
RocooFix熱更新流程:
1,執行一次 ./gradlew clean apkRelease 注意要開啓混淆
2,修復代碼中的bug
3,BaseApplication 取消註釋, RocooFix.init(this); //需要製作補丁時開啓
4,修改app.gradle中的 versionCode = 上個versionCode版本號+1 versionName = 上個版本號+1
取消 rocoo_fix 節點中的註釋:preVersionPath = 上個versionCode版本號+1
5,執行 ./gradlew clean apkRelease 注意要開啓混淆
6,取出 rocoo_fix目錄中對應版本號的path.jar
7,adb push path.jar /mnt/sdcard/xxxxxxx/hotfix
8,重啓app
備註:
每次生成path.jar的時候是與原來app版本diff。而不是和上一個補丁版本diff。
eg: 這次更新了1.1.1的補丁包(1.1.1補丁包是基於1.1.0版的app生成出來的),那麼1.1.2的補丁包還得是基於1.1.0去diff