以下内容主要涉及robust的入门介绍,其主要步骤在robust上已经说明,但是有必要在实践过程中进行说明。
工程配置
首先在项目的build.gradle文件中加入如下配置:
dependencies {
classpath 'com.meituan.robust:gradle-plugin:0.4.0'
classpath 'com.meituan.robust:auto-patch-plugin:0.4.0'
}
然后在app的build.gradle文件中加入如下配置:
制作补丁时将这个打开,auto-patch-plugin紧跟着com.android.application
//apply plugin: 'auto-patch-plugin'
打包apk时打开这个选项,关闭auto-patch-plugin
apply plugin: 'robust'
apply plugin: ‘robust’在打包apk时需要使用;
在打包补丁时,需要使用apply plugin: ‘auto-patch-plugin’。
添加依赖:
compile 'com.meituan.robust:robust:0.4.0'
在src同级目录新增robust.xml文件。
在robust.xml文件中,hotfixPackage代表需要修复的包名;patchPackname代表补丁生成的包名。
<!--需要热补的包名或者类名,这些包名下的所有类都被会插入代码-->
<packname name="hotfixPackage">
<name>com.android.robust</name>
</packname>
<!--补丁的包名-->
<patchPackname name="patchPackname">
<name>com.android.robust.patch</name>
</patchPackname>
这里有个小技巧,补丁的包名为了不影响修复的包名,建议两者不一致,这样不会影响修复包下的混淆设置。
按照正常方式打包后,可以在build/outputs目录找到mapping.txt和robust/methodsMap.robust,将这两个文件复制到与src同级的robust目录(没有请创建)。
制作补丁
public class SecondActivity extends AppCompatActivity {
@Override
@Modify
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView txt = (TextView) findViewById(R.id.txt);
txt.setText(getTxt());
}
@Add
private String getTxt(){
return "Robust successs...";
}
}
@Modify与@Add注解请查看官网语法。
制作补丁时将这个打开,auto-patch-plugin紧跟着com.android.application
apply plugin: 'auto-patch-plugin'
打包apk时打开这个选项,关闭auto-patch-plugin
//apply plugin: 'robust'
在命令行执行
gradlew clean assembleRelease --stacktrace --no-daemon
制作成功后会在build/outputs/robust目录找到patch.jar文件。
加载补丁
实现自己的加载补丁策略。
public class PatchManpulateImpl extends PatchManipulate {
@Override
protected List<Patch> fetchPatchList(Context context) {
Patch patch = new Patch();
patch.setName("test robust...");
patch.setLocalPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "robust" + File.separator + "patch");
patch.setTempPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "robust" + File.separator + "patch");
patch.setPatchesInfoImplClassFullName("com.android.robust.patch.PatchesInfoImpl");
List<Patch> patches = new ArrayList<>(4);
patches.add(patch);
return patches;
}
@Override
protected boolean verifyPatch(Context context, Patch patch) {
return true;
}
@Override
protected boolean ensurePatchExist(Patch patch) {
return true;
}
}
需要注意的是com.android.robust.patch.PatchesInfoImpl的包名需要与robust.xml中的patchPackname标签的配置保持一直。
<patchPackname name="patchPackname">
<name>com.android.robust.patch</name>
</patchPackname>
patch.setPatchesInfoImplClassFullName("com.android.robust.patch.PatchesInfoImpl");
将补丁push到手机。
adb push patch.jar /sdcard/crash/patch_temp.jar
加载补丁之后,可以看到SecondActivity 显示内容变化成修复后的内容。
演示代码地址
notes:
public class Patch implements Cloneable {
...
//原始补丁文件的路径,推荐放到私有目录
public String getLocalPath() {
return localPath + ".jar";
}
//解密之后的补丁文件,可以直接运行的补丁文件,建议加载之后立刻删除,保证安全性
public String getTempPath() {
return tempPath + "_temp" + ".jar";
}
...
}
在加载补丁时,正确的设置为。
patch.setTempPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "robust" + File.separator + "patch");
不带后缀.jar
同时还需要注意push到手机的patch包的文件名应该为patch_temp.jar,如上所示。