热修复学习四:AndFix详解一

本文详细介绍AndFix热修复技术的集成、使用流程及核心原理。从添加依赖、代码初始化到生成与安装补丁,逐步解析如何快速修复线上应用bug。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、AndFix的基本介绍

二、AndFix执行流程及核心原理

三、使用AndFix完成线上bug修复

1、集成阶段

 2、准备阶段

3、patch生成阶段

apkpatch命令及参数详解

使用apkpatch命令生成apatch包

patch安装阶段


一、AndFix的基本介绍

官方介绍:alibaba/AndFix

以后学习任何新技术,优先去官网查看文档,然后再考虑去看博客文章。

二、AndFix执行流程及核心原理

见官方介绍

三、使用AndFix完成线上bug修复

1、集成阶段

a、gradle中添加AndFix依赖

compile 'com.alipay.euler:andfix:0.5.0@aar'

b、在代码中完成AndFix的初始化

封装AndFixPatchManager

/**
 * Created by GuanSong
 * Description:管理AndFix所有的api
 * on 2019/8/2.
 */

public class AndFixPatchManager {

    private static AndFixPatchManager mInstance = null;

    private static PatchManager mPatchManager = null;

    private AndFixPatchManager() {

    }

    public static AndFixPatchManager getInstance() {
        if (mInstance == null) {
            synchronized (AndFixPatchManager.class) {
                if (mInstance == null) {
                    mInstance = new AndFixPatchManager();
                }
            }
        }
        return mInstance;
    }

    //初始化AndFix方法
    public void initPatch(Context context) {
        mPatchManager = new PatchManager(context);
        mPatchManager.init(Utils.getVersionName(context));
        mPatchManager.loadPatch();
    }

    //加载我们的patch文件
    public void addPatch(String path) {
        try {
            if (mPatchManager != null) {
                mPatchManager.addPatch(path);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

public class Utils {

    /**
     * 获取应用程序versionname
     *
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        String versionName = "1.0.0";
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return versionName;
    }
}



public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //完成andFix模块的初始化
        initAndFix();

    }

    private void initAndFix() {
        AndFixPatchManager.getInstance().initPatch(this);
    }

}

 2、准备阶段

  • build一个有bug的old apk并安装到手机
  • 分析问题解决bug后,build一个new apk

app的build.gradle文件中:

signingConfigs{
        //签名打包
        release {
            storeFile file("sumok2.jks")
            storePassword "123456"
            keyAlias "sumok2"
            keyPassword "123456"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

然后输入命令行:

gradlew assembleRelease

就可以顺利打包生成一个apk 

3、patch生成阶段

apkpatch命令及参数详解

安卓热修复,android打补丁,不用发版本就能实时的解决一些线上版本的bug

进入控制台:先输入 命令:dir  显示所有文件

再输入:apkpatch.bat 这个是在Windows平台下使用的命令

可以看到有两个命令:

usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>

usage: apkpatch -m <apatch_path...> -k <keystore> -p <***> -a <alias> -e <***>

第一个命令 usage: apkpatch -f 是用来生成一个patch文件

第二个命令usage: apkpatch -m 是用来将多个patch文件合并成一个

下面我们来生成一个apatch文件:

usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
 -a,--alias <alias>     alias.   
 -e,--epassword <***>   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.

usage: apkpatch -m <apatch_path...> -k <keystore> -p <***> -a <alias> -e <***>
 -a,--alias <alias>     alias.
 -e,--epassword <***>   entry password.
 -k,--keystore <loc>    keystore path.
 -m,--merge <loc...>    path of .apatch files.
 -n,--name <name>       patch name.
 -o,--out <dir>         output dir.
 -p,--kpassword <***>   keystore password.

以上有对每个字段或参数的作用的解释

我们在控制台输入以下命令:

需要注意的是,在该文件中要先生成新的apk然后拷贝进去,才会出现此正确结果,否则会报错 

命令:

apkpatch.bat -f new.apk -t old.apk -o output/ -k sumok2.jks -p 123456 -a sumok2 -e 123456

add modified Method:V  printLog()  in Class:Lcom/gs/sumok2/utils/Utils;

从这句话 可以看到我们改动了哪些地方

接下来我们看output文件夹:

已经生成了我们需要的apatch文件,这个名字太长了,我们可以给其重命名

使用apkpatch命令生成apatch包

patch安装阶段

  • 将apatch文件通过adb push到手机(或者用QQ传送给手机)
  • 使用已经安装的应用load我们的apatch文件
  • load成功后验证我们的bug是否修复

先把apatch文件push到手机上:

push命令:

E:\tools\apkpatch-1.0.3\output>adb push imooc.apatch /storage/emulated/0/Android/data/com.gs.sumok2/cache/apatch/imooc.a
patch
imooc.apatch: 1 file pushed. 0.0 MB/s (2859 bytes in 0.075s)

E:\tools\apkpatch-1.0.3\output>

可以看到提示push成功了。

然后点击“修复bug”按钮,这时候已经就修复成功了 

public class AndFixActivity extends AppCompatActivity {

    @BindView(R.id.btn1)
    Button btn1;
    @BindView(R.id.btn2)
    Button btn2;

    private static final String FILE_END = ".apatch";
    private String mPatchDir;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_and_fix);
        ButterKnife.bind(this);

        mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
        LogUtils.e(mPatchDir);

        /// storage/emulated/0/Android/data/com.gs.sumok2/cache/apatch/

        File file = new File(mPatchDir);
        if (file == null || file.exists()) {
            file.mkdir();
        }

    }

    @OnClick({R.id.btn1, R.id.btn2})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn1:
                createBug();
                break;
            case R.id.btn2:
                fixBug();
                break;
        }
    }

    private void createBug() {
        Utils.printLog();
    }

    private void fixBug() {
        AndFixPatchManager.getInstance().addPatch(getPatchName());
    }

    private String getPatchName() {
        return mPatchDir.concat("imooc").concat(FILE_END);
    }


}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.gs.sumok2.andfix.AndFixActivity">

    <Button
        android:id="@+id/btn1"
        style="@style/BtnCommon"
        android:text="1、产生bug" />

    <Button
        android:id="@+id/btn2"
        style="@style/BtnCommon"
        android:text="2、修复bug" />

</LinearLayout>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值