(十)Android AndFix 热修复使用

版权声明:本文为博主原创文章,未经博主允许不得转载。
本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。

一、AndFix 和 Tinker

热修复的作用以及好处不在这边描述,现在用的较多的热修复有 阿里的 AndFix腾讯的 Tinker

Tinker:通过分包技术,一个应用打包的时候可以达成多个 dex 包,当某个 dex 包中的代码出现 bug,后台进行修复后,单独打包这个 dex,替换原先错误的 dex,在加载 dex 的时候有个顺序,当已经加载过的 class 不会再次进行加载。这样我们只需要把修复后的 dex 插入到错误的 dex 之前即可。

AndFix :定位到错误的方法,可以单独对这个方法进行进行修复,打包成 dex。应用在加载完 dex 后对修复好的 class 的 Method 方法进行加载,从而达到修复的效果。

Tinker 缺点是需要整个 dex 进行替换,相比于 AndFix 来说,性能上有所欠缺,而且 Tinker 修复完之后需要重启。但是 AndFix 台依赖于底层的 Android 系统源码,所以兼容性上可能会有问题,最新的 sophix 是没有这个问题。

二、Android Studio 整合 AndFix

Android Studio 整合 AndFix 只需要在 app 下的 build.gradle 中添加依赖即可。(推荐)

implementation 'com.alipay.euler:andfix:0.3.1@aar'

这里写图片描述

也可以到 github 上下载源码,把源代码和 so 包拷贝到项目中或者整合成 Module 进行使用。

注:现在 github 上代码最新版本为 0.5.0,个人感觉其中 so 库文件有问题,会报错。替换 0.3.1 的 so 库就好了,暂时没看懂具体原因,有知道的麻烦给我留言。

这里写图片描述

官方 Github 链接

三、编写代码

MainActivity :

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = findViewById(R.id.sample_text);
        textView.setText("未修复");
    }

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

MainActivity 与 activity_main.xml 是很基本的一个布局,没有什么好讲的。

MainApplication :

public class MainApplication extends Application {
    private static final String TAG = "euler";

    private static final String APATCH_PATH = "/out.apatch";

    private PatchManager mPatchManager;

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化
        mPatchManager = new PatchManager(this);
        mPatchManager.init("1.0");
        Log.d(TAG, "inited.");

        // 加载 patch
        mPatchManager.loadPatch();
        Log.d(TAG, "apatch loaded.");

        try {
            //修复包路径(在这边写死)
            String patchFileString = "/tmp" + APATCH_PATH;
            mPatchManager.addPatch(patchFileString);
            Log.d(TAG, "apatch:" + patchFileString + " added.");
        } catch (IOException e) {
            Log.e(TAG, "", e);
        }
    }
}

主要内容在 MainApplication 中,在这边进行 PatchManager 的初始化与加载 apatch 文件。

四、生成 apatch

对应用进行打包,打包 apk 的时候,需要使用到证书,最好不要使用系统默认的证书,在后面生产修复包的时候需要用到证书的密码,别名等,避免输错导致生成修复包失败。

修改 MainActivity 中 TextView 显示的文字,重新打包 apk。

MainActivity :

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = findViewById(R.id.sample_text);
        textView.setText("未修复");
    }

}

用 apkpatch 工具对以上两个新老 apk 进行生成修复包,apkpatch 工具在 Github 上有。在命令行窗口,切换到 apkpatch 所在的目录,进行生成修复包。

apkpatch -f ‘新apk路径’ -t‘ 旧apk的路径’ -o ‘生成的补丁包的输出目录’ -k‘ 打包签名的keystore文件路径’ -p ‘签名文件密码’ -a‘ keystore别名’ -e ’keyStore entry的密码‘

这里写图片描述
在这过程中要是执行错误的话,确认证书的各个参数是否正确,不确定的重新生成一个新的证书吧。

执行完毕之后会在对应的目录下生成一个 out 文件夹。

这里写图片描述

在 out 文件夹下会有一个 apatch 文件的存在,把名字改为 “out.apatch”,(与 MainActicity 中相对应)
这里写图片描述

五、安装与修复

安装旧 apk,并运行。界面显示 “未修复”;

这里写图片描述

把生成的修复包 out.apatch 手动 push 到 /tmp 文件夹下。
这里写图片描述

重启启动应用,则进行修复包的加载和修复。
这里写图片描述

六、限制

  1. 不支持 YunOS (java 代码进行判断,拒绝处理)
  2. 无法添加新类和新的字段 (可以添加新的方法)
  3. 需要使用加固前的 apk 制作补丁,但是这样补丁文件很容易被反编译,也就是修改过的类源码容易泄露。
  4. 使用加固平台可能会使热补丁功能失效。
  5. andfix 不支持布局资源等的修改。

七、附

官方 Github 链接

猜你喜欢

转载自blog.csdn.net/qq_18983205/article/details/79858656