热更新: 就是在应用无需重新安装情况下实现更新,从而实现动态修复功能。
在热更新之前,如果线上的应用出现bug, 是需要用户重新下载然后安装,这样的操作对用户来说肯定是不能接受的,什么软件,时不时就重新下载安装,用户体验极差, 热更新出现之后,这样的问题就可以得到解决,在用户无感知的情况下就可以把bug修复。
目前比较火的热修复的分为阿里系、腾讯系、 其他大厂。
- 阿里系 : DeXposed 、 andfix 从底层二进制入手 (c语言)。
- 腾讯系 : tinker 、Qzone 从类加载入手 。
- 美团: Robust 从类加载入手 。
下面给出几个大厂的框架区别
在集成热更新之前,比较过几个框架,最终还是选择Tinker。 下面就介绍集成Tinker步骤。 跑通tinker中的demo
源码 : https://github.com/Tencent/tinker
1: 在工程目录下的build.gradle中,添加tinker-patch-gradle-plugin的依赖
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1')
2: 然后在app的gradle文件app/build.gradle, 需要添加tinker的库依赖以及apply tinker的gradle插件。
implementation('com.tencent.tinker:tinker-android-lib:1.9.1')
implementation("com.tencent.tinker:tinker-android-loader:1.9.1") { changing = true }
annotationProcessor("com.tencent.tinker:tinker-android-anno:1.9.1") { changing = true }
implementation "com.android.support:multidex:1.0.1"
具体的可以参考 tinker 中的demo中的build.gradle文件。
3: copy demo中的代码到自己的工程中。
4:添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
经过上面的步骤,前面的工作是差不多集成完了,但是build的时候 会出现很多问题, 在build出现错误时,请看下面的常见错误。
现在就写代码来测试下。
1 : 界面就两个按钮 和textview结果显示 , 长这样。
2:点击“写入pitch文件”执行的代码
public void doHotFix(Context context) throws IllegalAccessException, NoSuchFieldException, ClassNotFoundException {
if (context == null) {
return;
}
mContext=context;
OkHttpClient client=new OkHttpClient();
Request request= new Request.Builder().url(url).get().build();
Call call=client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("TAG", "onFailure: " );
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("51app", "onSuccess");
FileOutputStream fos = null;
try {
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
File apkFile = new File(sdPath, "patch_signed_7zip");
Log.e("51app", "size==" + apkFile.getTotalSpace());
if (apkFile.exists()) {
apkFile.delete();
}
apkFile.createNewFile();
fos = new FileOutputStream(apkFile);
fos.write(response.body().bytes());
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (fos != null)
fos.close();
} catch (IOException e) {
Log.e("51app", "downloadPatch IOException:");
e.printStackTrace();
}
}
}
});
//加载补丁包
TinkerInstaller.onReceiveUpgradePatch(MainActivity.this, Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip");
}
代码的功能就是从服务器获取patch_signed_7zip文件,然后写入到本地, 在调用Tinker中的方法来修复。怎么生成这个差量文件patch_signed_7zip 下面会说到。
3: 点击“计算获取结果” 按钮 执行的代码
btn_result.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int a=12;
int b=0;
int result=a/b;
tv_result.setText(result);
}
});
点击执行的时候 ,肯定是崩溃的。会抛ArithmeticException divide by Zero异常。
4: 在activity生命周期方法中的onPause和onResume 调用tinker中的接口。
@Override
protected void onResume() {
super.onResume();
Utils.setBackground(false);
}
@Override
protected void onPause() {
super.onPause();
Utils.setBackground(true);
}
5: 生成基准包, 双击这个。也可以直接运行生成 然后在build目录下会生成,
安装下这个基准包,然后点击’获取结果按钮‘ 程序会崩溃
6:修改app的gradle文件app/build.gradle
7:修复那个基准包的异常,点击“计算获取结果” 按钮 执行的代码
btn_result.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int a=12;
int b=0;
if (b==0){
tv_result.setText("除数为0拉");
return;
}
int result=a/b;
tv_result.setText(result);
}
});
除数为0 时 直接return。 就不会崩溃了。
8: 生成差量包, 双击tinkerPatchDebug。 然后在该build下的目录生成。
- patch_signed.apk 签过名的
- patch_unsigned.apk 未签过名的
- patch_signed_7zip.apk 经过压缩的签名过的包
然后把patch_signed_7zip.apk 这个文件放在服务器上。 就可以测试了。 (我测试时把这个名字该了), 还是运行那个基准包。
可以看到我们首先点击’计算获取结果‘是会崩溃的, 然后我们点击’‘
写入pitch文件 如果成功会有success提示 失败的话也会又提示 现在我们看到succeed 说明已经合成成功了为什么还是崩溃呢。
原因是tinker不是立即生效的。
合成成功后,我们手动杀掉这个应用的进程,然后再打开 点击“获取计算结果” 就不会崩溃了,说明热更新更能集成完毕。
常见问题
1 :再生成差量包时 versioncode 需要+1 不然合成的时 会失败。
2:如果在生成差量文件时 build出现异常导致 生成失败的话 就把这个值设置为true
3:tinkerid 我的是设置为 git的版本号。 也可以设置为 版本号。 保持唯一性, 不然的话 build会失败。
4: 关掉androidsudio 中的 install run 功能。 不然也会build失败
感谢关注我的公众号
参考文档
Tinker接入指南 :https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
常见问题 : https://github.com/Tencent/tinker/wiki/Tinker-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
热修复原理 :
https://blog.csdn.net/csdn_lqr/article/details/78534065
来源:CSDN
作者:游戏人日常
链接:https://blog.csdn.net/song_shui_lin/article/details/88593899