热修复解决的问题
- 刚发布就发现了严重的bug,需要及时修复
- 有些小功能需要及时地推送给用户,例如淘宝双十一,搞了点活动,想让用户马上就使用到,不需要用户去再次下载更新
热修复
如何从本质上实现热修复功能
下图摘自《深入探索Android热修复技术原理》
市面上的热修复方案
AndFix
流程简介
代码
gradle添加依赖
implementation 'com.alipay.euler:andfix:0.5.0@aar'//引入andfix
代码里初始化
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
AndfixPatchManager.getInstance().initPatch(this);
}
}
public class AndfixPatchManager {
private static AndfixPatchManager mInstance = null;
private static PatchManager mPatchManager = null;
public static AndfixPatchManager getInstance() {
if (mInstance == null) {
synchronized (AndfixPatchManager.class) {
if (mInstance == null) {
mInstance = new AndfixPatchManager();
}
}
}
return mInstance;
}
/**
* 初始化andfix
*
* @param context
*/
public void initPatch(Context context) {
mPatchManager = new PatchManager(context);
mPatchManager.init(Utils.getVersionName(context));
mPatchManager.loadPatch();
}
/**
* 加载Patch文件
*
* @param path
*/
public void addPatch(String path) {
if (mPatchManager != null) {
try {
mPatchManager.addPatch(path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private fun setListener() {
create_bug.setOnClickListener {
Utils.printBug(this)
}
fix_bug.setOnClickListener {
AndfixPatchManager.getInstance().addPatch(getPatchName())
}
}
生成patch文件
- 先下载工具
2. 打包
> 必须打出签名后的apk
> 打一个有bug的apk
> 打一个修复bud的apk
使用工具生成apatch包
- 命令行:
./apkpatch.sh -f app-new.apk -t app-old.apk -o output/ -k keystore -p 111111 -a cjx -e 111111
- 把补丁文件放到手机里,注意路径必须是代码里指定的那个
- 安装有bug的apk
6. 开始操作
第一次点击按钮产生bug按钮,直接奔溃
第二次打开后,先点击第二个修复按钮,再点击第一个bug按钮,吐司弹出,log正常打印
流程
热修复原理
简单说市面上两种代码修复原理
我们目前只是谈代码修复,还没涉及到资源文件修复和so修复
Andfix底层置换原理
AndFix采用的是直接在已经加载的类中的native层替换掉原有的方法,实在原有类基础上进行修改的。
阅读了AndFix的java层源码,层层调用其核心在于replaceMethod这个函数,而这个函数是一个native层的函数,所以具体实现在C层,
private static native void replaceMethod(Method dest, Method src);
底层置换法大概就是这个样子
至于腾讯的类加载方案,就需要先补充点预热知识
- dex
- JVM
- classLoader的源码