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