Android 热修复 - AndFix 使用心得

来源:互联网 发布:linux创建多级文件夹 编辑:程序博客网 时间:2024/06/06 21:38

前言:
对于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
原创粉丝点击