比较Dexposed:
Andfix与Dexposed同出自于阿里开源项目,主要是为了实现Android在线修复
项目整合:
直接添加 AndFix aar 到项目中的 编译依赖库中。
maven 依赖:
<dependency>
<groupId>com.alipay.euler</groupId>
<artifactId>andfix</artifactId>
<version>0.3.0</version>
<type>aar</type>
</dependency>
或者是Gradle依赖:
dependencies {
compile 'com.alipay.euler:andfix:0.3.0@aar'
}
如何使用:
1 . 初始化PatchManager:
patchManager = new PatchManager(context);
patchManager.init(appversion);//current version
2 . 载入补丁包
越早的载入补丁包越好,通常来说,我们一般都会在自定义的Application中的onCreate方法里面载入补丁包。即:
patchManager.loadPatch();
3 . 添加补丁包
新的补丁包,下载后调用addPatch方法添加补丁。这个补丁会立即生效。
patchManager.addPatch(path);//path of the patch file that be downloaded
ProGuard混淆设置
确保一些class文件在使用的时候不被proguard所混淆,当然,proguard的混淆配置如下所示:
原生method
com.euler.cloudfix.CloudFix
annotation
com.euler.cloudfix.annotation.MethodReplace
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
native <methods>;
}
4、使用apkpatch工具生成apatch文件
制作补丁是需要专门的工具的。这里有一个工具,叫做 apkpatch的工具,用来制作AndFix的补丁
如:
apkpatch -f ./new/sample-relese.apk -t ./old/sample-relese.apk -o ./out -k ./old/sample.keystore -p 123456 -a testkey -e 123456
5、把xxx.apatch拷贝到手机对应的目录下,运行项目,大功告成。
测试:
1、新增方法或者修改,删除方法均可以hot fix
2、新增类并且调用,app异常退出
3、在loadPatch之后,删除手机中的xxx.apatch文件,fix任然有效,框架保留了缓存(data/data/com.eular.andfix/files)
4、版本不对应,运行patch包崩溃
5、loadPatch() 在子线程操作 Thread suspend timeout
原理:
非native代码,主要有3个manager
PatchManager:init初始化,建立一些目录;把.apatch文件拷贝到data目录下备份,生成patch对象;然后通过oadPatch调用AndfixManager的fix();
AndfixManager:fix()中对apk,dex验证,然后调用fixClass(),得到要代替的方法class 和method ,调用replaceMethod();
AndFix: addreplaceMethod()方法调用了native方法replaceMethod;
另外几个个类是辅助类:Patch, Compat, FillUtil
这是非native类的时序图,结合代码方便理解
以5.0为例,在art运行时,调用流程为1->2->3->4
对于art运行时,Java层与native层交互的入口有以下几种:
存在ArtMethod::entry_point_from_compiled_code_和ArtMethod::entry_point_from_interpreter_和ArtMethod::entry_point_from_jni
AndFix是在调用这些入口之前,用aptch的方法代替了src的方法,然后调用jni入口函数,实现hot-fix
对于dvm运行时,其实和Dexposed原理相似,修改了jni层交互入口nativeFunc函数,用自己的分发器dalvik_dispatcher代替了,在dalvik_dispatcher中
做自己想做的事情,与Dexposed的区别在于,具体的实现是在Java层hook的,而AndFix把这部分工作给封装了,它帮我们在native完成的:
就这么多,结合代码和实例大家可以自己研究下