Android 热修复 - AndFix 使用心得

前言:
对于AndFix的深层次思想和原理,我一直半懂不懂,介绍一个讲述原理的博文 Android App 线上热修复方案,其中所说的Xposed的原理操作看得萌萌哒,等慢慢消化吧,本文只是详细记录下,我在使用AndFix的一些步骤和坑,耐心!耐心!耐心!(重要的事情说3遍)


第一步:下载
虽然可有可无,不过也是第一步,github:https://github.com/alibaba/AndFix


第二部:解压缩
恩,真正使用的时候,我们所需要的一切在解压后的tools目录下的压缩包里面,解压 apkpatch-1.0.3.zip 后的目录如下:

这里写图片描述

到这里,准备工作都已经做完了。


第三部:代码编写
其实在github上已经说得很清楚了,不过想想还是把代码具体的写出来吧。
对于Patch的初始化,当然越早越好,这个没什么异议,那么就放在Application里面

public class MyApplication extends Application {

    public static MyApplication instance;

    public static final String TAG = "MyApplication";

    public static PatchManager patchManager;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        DirUtils.initDir();
        initPatch();

    }

    private void initPatch() {
        try {
            patchManager = new PatchManager(this);
            String versionName = this.getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            Log.d(TAG, versionName);
            patchManager.init(versionName);
            patchManager.loadPatch();
        } catch (Exception e) {
        }
    }
}

然后在MainActivity里面,我加入了以下代码,并且先提供下本地目录的路径工具 类

public class DirUtils {

    public static final String ROOT =
            Environment.getExternalStorageDirectory() + File.separator +
                    MyApplication.instance.getString(R.string.app_name) + File.separator;

    public static void initDir() {
        File dir = new File(ROOT);
        if (!dir.exists()) {
            if (dir.mkdirs()) {
            }
        }
    }

}
public class MainActivity extends AppCompatActivity {

    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            String versionName = packageInfo.versionName;
            int versionCode = packageInfo.versionCode;
            tv.setText("versionCode=" + versionCode + " : versionName=" + versionName + " : i am a 大八个");
//            tv.setText("versionCode=" + versionCode + " : versionName=" + versionName + " : I am not a 大八个" + " 哈哈哈哈");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        tv.postDelayed(new Runnable() {
            @Override
            public void run() {
                File file = new File(DirUtils.ROOT, "fix.apatch");
                if (file.exists()) {
                    Log.d(MyApplication.TAG, "fix.apatch exists");
                    try {
                        MyApplication.patchManager.addPatch(file.getAbsolutePath());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, 3000);
    }

    public void jump(View view) {
        startActivity(new Intent(this, SecondActivity.class));
    }

}

这是bug的版本,修复的代码就是把注释的那行代码放开就行了,这里我已经约定好patch的名字就是 fix.patch,然后模拟加载这个补丁。
这儿我没有用到服务器,具体的测试步骤是这样的:
1.把bug版本的apk打包完成,装在手机上,就是模拟用户已经存在在手机上的apk
2.将fix版本的apk打包,然后制作.apatch补丁文件,存储到我约定的路径下,这里就是模拟下载
3.当你重新打开apk,其实就完成了补丁的修复,如果再一次打开apk就可以看到bug被修复了


具体如何生成 .apatch:
在相同的 versionCode 和 versionName 下,才能成功的打出 .apatch的包,如果你的版本标识不一样会报错,这样就无法成功把补丁打出来:

这里写图片描述

当你把bug版本的apk和fix版本的apk,都打出来之后,使用AndFix提供的tool,也就是前面所说的压缩包,另外,我用的是Mac,所以使用的时候用的就是 .sh后缀的文件,成功的命令如下:

这里写图片描述

切换到解压后的apkpatch-1.0.3目录下

 ./apkpatch.sh -f /Users/chenjiahuan/Desktop/app-release-fix.apk -t /Users/chenjiahuan/Desktop/app-release-bug.apk -o /Users/chenjiahuan/Desktop/apkpatch-output -k /Users/chenjiahuan/Desktop/123456.keystore -p 123456 -a 123456 -e 123456

./apkpatch.sh 具体的命令脚本
-f new_fixed_apk 修复完成的apk
-t old_bug_apke 线上待修复的apk
-o patch_output 补丁patch的输出目录
-k keystore 签名文件
-p pwd 签名密码
-a alias 别名
-e alias_pwd 别名密码

一切OK的话就打出了

这里写图片描述

fix.apatch 就是我需要的补丁,然后按照我之前的测试流程就可以了。


补充:
真正上线的时候肯定不会这么简单的,补丁版本的控制下载流程,包括混淆、加密这些都可能存在着坑,不过程序员不就是专业填坑的么…
另外需要知道的是,AndFix并不是说patch好了之后就能看到,你需要重新打开app,这也是我MainActivity中为什么会有跳转的代码,事实证明,bug修复后,需要用户重新打开app。

这样,我使用的具体流程就是这样了,之后我还会讲一下另外一种热修复方案,基于ClassLoader的,那是我比较熟悉的一种方案,不过过程麻烦了点,代码就不需要贴了吧,都在上面了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值