一、简介
AndFix是阿里开源的热修复方案,是轻量级的。AndFix能在线修复的bug,能立即生效不需要重启。不过Andfix只能修复方法级别的bug,不能新增方法,也不能修改资源和so文件等。
二、Gradle中添加AndFix依赖
implementation 'com.alipay.euler:andfix:0.5.0@aar'
三、代码中完成AndFix的初始化
public class MainActivity extends AppCompatActivity {
private static final String FILE_END = ".apatch";
private String mPatchDir;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_create_bug).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Utils.PrintLog();
}
});
findViewById(R.id.btn_fix_bug).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AndFixPatchManager.getInstance().addPatch(getPatchName());
}
});
mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
//是为了创建我们的文件夹
File file = new File(mPatchDir);
if (file == null || !file.exists()) {
file.mkdir();
}
}
private String getPatchName() {
return mPatchDir.concat("imooc").concat(FILE_END);
}
}
public class AndFixPatchManager {
private static AndFixPatchManager mInstance = null;
private PatchManager mPatchManager =null;
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){
if(mPatchManager !=null){
try {
mPatchManager.addPatch(path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initAndFix();
}
private void initAndFix() {
AndFixPatchManager.getInstance().initPatch(this);
}
}
public class Utils {
public static String getVersionName(Context context) {
String versionName = "1.0.0";
PackageManager pm = context.getPackageManager();
PackageInfo packageInfo = null;
try {
packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
versionName = packageInfo.versionName;
return versionName;
}
public static void PrintLog() {
String error = null;
Log.e("lalalla", error);
}
}
四、apkpatch命令生成apatch包
下载官方提供的工具apkpatch,下载下来后的文件如下图所示
- build一个old.apk 并安装到手机
- 修改一些功能后,build一个new.apk
- 把签名文件sign.jks也复制进
来如下图所示:
如果没有配置环境变量,可以直接到apkpatch文件夹内部,才可以使用apkpatch命令。
我是没有配置环境变量的,先看下apkpatch命令有哪些参数
提供了2个命令,
- usage: apkpatch -f 是用来生成一个patch文件
- usage: apkpatch -m 是用来将多个patch文件合并成一个
接下来看下apkpatch -f 是如何生成apatch文件
为啥生成apatch文件也需要指定签名,其实跟我们使用apk需要签名的原因是一样的,防止恶意的篡改内容。
生成了一个outputs文件夹
打开outputs文件夹,里面生成真正的补丁文件imooc.apatch(我重命名过)
这样我们就生成了补丁文件
小技巧
这个生成apatch文件的命令很长,我们可以生成一个脚本。
创建一个create_patch.bat 文件 然后把这行命令复制进去
apkpatch.bat -f new.apk -t old.apk -o outputs/ -k sign.jks -p 888888 -a geely -e 888888
补丁文件的安装
将apatch文件通过 adb push到手机指定的文件目录下
在手机的该目录下就可以看到补丁包
接下来点击FixBug 然后点击产生Bug,发现就修复完成了。
AndFix只能修复方法级别的bug,但是实际开发中资源、配置都可能产生bug,那么可以选择微信的Tinker。