热修复定义:在应用上线后出现bug需要及时修复时,不用再发新的安装包,只需要发布补丁包(发送到服务器上,下发到客户端),在客户无感知下修复掉bug
热修复的使用
热修复的框架有很多,这里选择Tinker(是微信开源的一个热修复解决方案,支持dex、库和资源更新,无需重新安装apk。https:///Tencent/tinker),Tinker使用较为复杂,所以,可以直接使用Tinker,也可以使用腾讯 Bugly 服务集成Tinker热修复,后者提供了补丁管理服务。
学习Tinker的使用,需先了解 Android APK打包签名配置。
建议根据官方案例工程进行使用,按照Bugle文档由于版本问题会导致无法使用。https:///BuglyDevTeam/Bugle-Android-Demo/tree/master/BuglyHotfixDemo
1、配置Bugly
(1)在配置Bugly时,有几个版本需要注意:
① 根目录下的“build.gradle”(建议使用3.X版本)
...
dependencies{
classpath 'com.android.tools.build:gradle:3.2.0'
}classpath ‘com.android.tools.build:gradle:3.2.0’ 的作用是,声明一个Gradle插件,gradle:3.2.0是Gradle插件版本号
② gradle/wrapper/gradle-wrapper.properties
distributionUri=https\://services.gradle.org/distributions/gradle-4.6-all.zip上述是Gradle版本配置位置
gradle-wrapper.properties中配置的是的Gradle的版本.
build.gradle中的依赖指定的是Gradle插件的版本.
关于两者的区别,见 (3条消息) AS中 Gradle和Gradle插件区别_飞露的博客-CSDN博客_gradle和gradle插件
(2)工程根目录下 “build.gradle” 文件中添加:
buildscripts{
...
dependencies{
//=======添加下面一句========
classpath "com.tencent.bugly:tinker-support:1.2.0" //添加tinkersupport插件,其中lastest.release指拉取最新版本,也可以指定明确版本号,例如1.0.4
}
}(3)在app module的“build.gradle" 文件中添加:
//========添加第一句===========
apply from:'tinker-support.gradle'
dependencies{
//===========添加第二句=============
implementation 'com.tencent.tinker:tinker-android-lib:1.9.14.10'
//===========添加第三句=============
implementation 'com.tencent.bugly:crashreport_upgrade:1.5.0'
}(4)在项目源码中加入:SampleApplication与SampleApplicationLike类,并且将SampleApplication注册进入AndroidManifest.xml
<manifest>
<application
android:name=".SampleApplication"
...>
...
</application>
</manifest>可直接从官网示例代码中,将上述两个类赋值到自己的工程当中。两个类中需更改的地方:
1)SampleApplication
public class SampleApplication extends TinkerApplication{
//注意:第二个参数需要改为自己工程中的SampleApplicationLike的包名
public SampleApplication(){
super(ShareConstants.TINKER_ENABLE_ALL,
"com.enjoy.hotfixdemo.SampleApplicationLike",
"com.tencent.tinker.loader.TinkerLoader",
false,
true);
}
}2)SampleApplicationLike
onCreate(){
...
//第二个参数,appId,替换成你的在Bugly平台中申请的appId
Bugly.init(getApplication(), "zxyyouaregood",true)
}appId就是在Bugly的“我的产品”中创建生成的
2、打包项目工程(含bug)为apk文件:
//项目工程主要内容 点击设置的唯一按钮时 抛出异常
public void test{
//Log.i("Hotfix","test: fix");
throw new IllegalStateException("出错啦!");
}
这里打包为 release 版本,注意assembleRelease。
具体操作:
(1)进入build.gradle文件:
//build.gradle
android{
compileSdkVersion 30
...
//下面是签名
signingConfigs{
config{
keyAlias 'enjoy'
keyPassword '123456'
storeFile file('enjoy.keystore')
storePassword '123456'
}
}
buildTypes{
release{
//针对Release版本的签名
signingConfig signingConfigs.config
minifyEnabled true //开启混淆
proguardFiles getDefaultProguardFile('proguard-android-')
}
}
}(2)开启混淆后,需要注意的是,在混淆配置文件proguard-rules.pro中,需要加入混淆对于Tinker的规则:
//proguard-rules.pro文件
-dontware com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
//tinker混淆规则
-dontware com.tencent.tinker.**
-keep class com.tencent.tinker.** {*;}
-keep class androidx.**{*;}(3)还有一点需要注意,在build.gradle文件中,引入的tinker-support.gradle文件,可以直接从官方Demo中copy出来
//build.gradle
...
apply from: 'tinker-support.gradle' //引入的tinker-support.gradle文件
android{
compileSdkVersion 30
...
//下面是签名
signingConfigs{
config{
keyAlias 'enjoy'
keyPassword '123456'
storeFile file('enjoy.keystore')
storePassword '123456'
}
}
buildTypes{
release{
//针对Release版本的签名
signingConfig signingConfigs.config
minifyEnabled true //开启混淆
proguardFiles getDefaultProguardFile('proguard-android-')
}
}
}修改tinker-support.gradle文件:
当打release包时,文件内容中有release;当打debug包时,将内容中的release改为debug
//打补丁包时,需对baseApkDir变量进行修改,该变量值内容填写为每次构建生成的基准包目录
def baseApkDir = "app-1222-21-11-16"
tinkerSupport{
...
//当打debug包时,将内容中的release改为debug
//除了这一处还有几处
baseApk = '${bakPath}/{baseApkDir}/app-release.apk'
...
}(4)双击assembleRelease,制作一个Release包
3、安装有Bug的测试App
4、修复Bug,生成补丁包
public void test{
Log.i("Hotfix","test: fix");
//throw new IllegalStateException("出错啦!");
}
针对该目录下的release包,制作对应的补丁包
(1)在右侧的目录中双击 buildTinkerPatchRelease

执行完成后,

但是,使用补丁包时,不能使用上述目录中的apk文件,而应该使用app/build/outputs/patch/release目录下的apk文件,将 path_signed_7zip.apk文件 上传到Bugly服务器(当然也可以使用自己的服务器),然后在 “热更新 -> 应用升级” 中下发补丁包。
(2)下发完成后,再次使用应用时,会弹出更新提示,“检测到当前版本需要重启,是否重启应用?”。更新后,bug被修复。
















