介绍

Andfix全称是Android hot-fix,是阿里开源的一个android热修复框架([GitHub地址](https://github.com/alibaba/AndFix)),允许在不发布新的安卓版本的情况下去修复线上应用的bug,从2.3到7.0都是支持的(但是实际上他的兼容性并没有想象中的那么好!)。andfix生成差异包的后缀名是.apatch。它只能适用于方法级别的替换,使用场景有限,不能够新增类,新增方法。AndFix的实现原理是方法体的替换。如下图:

android 支持热修复吗 android热修复框架_android 支持热修复吗

AndFix的集成

在gradle中添加AndFix依赖

在app moudle中的build.gradle中添加AndFix的依赖。
compile 'com.alipay.euler:andfix:0.5.0@aar' //引入andfix 模块

Initialize PatchManager与Load patch

AndFix的初始化应该越早越好,所以我们在application中去调用他的初始化方法。
private static PatchManager mPatchManager;

    //初始化AndFix方法
    public void intiPatch(Context context){
        //需要当前应用的版本号
        mPatchManager.init(Utils.getVersionName(context));
        //load
        mPatchManager.loadPatch();
    }
public static String getVersionName(Context context){
        String versionName = "1.0.0";
        PackageManager packageManager = context.getPackageManager();
        try {
            PackageInfo pi = packageManager.getPackageInfo(context.getPackageName(),0);
            versionName = pi.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return versionName;
    }

Add patch

在需要的地方调用加载patch文件的方法(比如说:apatch从服务器下载完成时)。这个时候我们的bug就修复了。
//加载patch文件
    public void addPatch(String path){
        if(mPatchManager!=null){
            try {
                mPatchManager.addPatch(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

AndFix的使用

首先我们先构建出存放patch文件的路径,即我们要加载的patch文件的路径。
//patch文件后缀名
    private static final String FILE_END = ".apatch";
    //patch文件的路径
    private String mPatchDir;

    mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
    ......
    //创建文件夹
    File file = new File(mPatchDir);
    if(file==null || !file.exists()){
        file.mkdir();
    }   
    ......
     //构造patch文件名
    private String getPatchName() {
        return mPatchDir.concat("xq_sq").concat(FILE_END);
    }
生成2个按钮,一个用于产生bug,一个用于加载patch文件修复bug
//产生bug
    public void createBug(View view){
        Utils.printLog();
    }

    //修复bug
    public void fixBug(View view){
        AndfixPatchManager.getInstance().addPatch(getPatchName());
    }

    public static void printLog(){
        String error =null;
        Log.v("xq_msg",error);
    }
然后打出有bug的apk(签名版),先保存一份(我们后面还需要用它来生成patch文件),再安装到手机中。然后下用于生成patch文件的apkpatch文件(包括下图中圈出来的3个文件,其他文件是生成patch文件需要的)(文章最后附有下载地址和源码)来准备生成我们的patch文件。

android 支持热修复吗 android热修复框架_初始化_02


生成patch文件的命令

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.
我们先需要去修改我们的apk中的那个bug,然后生成新的apk文件,然后将对应的文件放到我们的apkpatch文件夹中再控制台中执行我们的命令就可以在output中生成我们的patch文件了。
apkpatch -f andfix_fix.apk -t andfix_bug.apk -o output/ -k xq_test.jks -p xq123456 -a xq_test -e xq123456

android 支持热修复吗 android热修复框架_热修复_03


在使用命令生成patch文件的时候,他也告诉了你这2个apk文件有哪里不同,修改了哪些地方

android 支持热修复吗 android热修复框架_初始化_04


生成patch文件之后我们可以使用adb命令将它放入我们上面定义的patch文件的路径中。

然后点击fixBug的按钮,来加载我们的patch文件,这个时候bug就修复了,你会发现点击createBug按钮应用也不会崩溃了。

AndFix的混淆规则

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

源码下载地址和apkpatch文件下载地址

源码及文件