Android AndFix 热修复 使用

Android AndFix 热修复 使用

AndFix,阿里开源的一个Android热补丁框架。AndFix 通过加载器读取一个dex文件中的类,并找到被注解标记到的要修复的方法,再通过jni在C层替换掉原本出BUG的方法的指针,从而达到热修复的目的。

使用

AndFix GitHub

添加依赖

dependencies {
    compile 'com.alipay.euler:andfix:0.4.0@aar'
}

初始化 PatchManager

patchManager = new PatchManager(context);
patchManager.init(appversion);//current version

//可以用这句话获取appversion
//String appversion= getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
注意每次appversion变更都会导致所有补丁被删除,如果appversion没有改变,则会加载已经保存的所有补丁。

加载已存在的补丁

patchManager.loadPatch();

你应该尽可能早地加载补丁,通常,在应用程序的初始化阶段(如Application.onCreate())。

添加新补丁

patchManager.addPatch(path);

要保证每次加载的补丁的名称不同,如果相同补丁名称的patch已存在,则不会重新加载

if (dest.exists()) {
    Log.d(TAG, "patch [" + path + "] has be loaded.");
    return;
}

addPatch()会将补丁复制到/data/data/app包名/files/apatch_out 文件夹下
然后如果复制完成后,如果是patch文件,则回调用loadPatch()方法,自己无需再调用loadPatch()方法

具体源码如下

private Patch addPatch(File file) {
    Patch patch = null;
    if (file.getName().endsWith(SUFFIX)) {
        try {
            patch = new Patch(file);
            mPatchs.add(patch);
        } catch (IOException e) {
            Log.e(TAG, "addPatch", e);
        }
    }
    return patch;
}

public void addPatch(String path) throws IOException {
    File src = new File(path);
    File dest = new File(mPatchDir, src.getName());
    if(!src.exists()){
        throw new FileNotFoundException(path);
    }
    if (dest.exists()) {
        Log.d(TAG, "patch [" + path + "] has be loaded.");
        return;
    }
    FileUtil.copyFile(src, dest);// copy to patch's directory
    Patch patch = addPatch(dest);
    if (patch != null) {
        loadPatch(patch);
    }
}

生成补丁

  1. 生成一个apk文件(APK1)
  2. 修改部分代码(比如说修复了一些bug)
  3. 生成新的apk文件(APK2)
  4. 通过官方提供的 工具 生成.patch补丁,需传入APK1和APK2和签名文件
#
usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>  
-a,--alias <alias>     keystore entry alias.  
-e,--epassword <***>   keystore entry password.  
-f,--from <loc>        new Apk file path.  
-k,--keystore <loc>    keystore path.  
-n,--name <name>       patch name.  
-o,--out <dir>          output dir.  
-p,--kpassword <***>   keystore password.  
-t,--to <loc>          old Apk file path.  
示例
apkpatch -f E:\VersionManager\WorkSpace\Test\MyTest727\app\new.apk -t E:\VersionManager\WorkSpace\Test\MyTest727\app\MyTest727.apk -o E:\ -k D:\ethanco.jks -p z0159990320 -a zhk -e z0159990320

进行替换

将补丁下载或复制到手机指定目录,然后就可以用 addpatch(patch文件路径) 进行替换了。

加载过的补丁会被保存到data/packagename/files/apatch_opt目录下,所以下载过来的补丁用过一次就可以删除了。

大致原理

apkpatch将两个apk做一次对比,然后找出不同的部分。可以看到生成的apatch了文件,后缀改成zip再解压开,里面有一个dex文件。通过jadx查看一下源码,里面就是被修复的代码所在的类文件,这些更改过的类都加上了一个_CF的后缀,并且变动的方法都被加上了一个叫@MethodReplace的annotation,通过clazz和method指定了需要替换的方法。
然后客户端sdk得到补丁文件后就会根据annotation来寻找需要替换的方法。最后由JNI层完成方法的替换。

多次打补丁

如果本地保存了多个补丁,那么AndFix会按照补丁生成的时间顺序加载补丁。具体是根据.apatch文件中的PATCH.MF的字段Created-Time。

局限性

  • 不支持YunOS
  • 无法添加新类和新的字段
  • 需要使用加固前的apk制作补丁,但是补丁文件很容易被反编译,也就是修改过的类源码容易泄露。
  • 使用加固平台可能会使热补丁功能失效(看到有人在360加固提了这个问题,自己还未验证)。

文/seewhy(简书作者)
原文链接:http://www.jianshu.com/p/479b8c7ec3e3

混淆

-printmapping mapping.txt
首先需要生成mapping.txt记录混淆规则,之后可以把print mapping 这句话注释掉,每次只使用applymapping。
-applymapping mapping.txt
然后在下面加上

-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
    native <methods>;
}

源码解析

Alibaba-AndFix Bug热修复框架原理及源码解析
AndFix解析——(上)

AndFix Demo

AndFix Demo

参考

AndFix使用说明

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值