关于热修复为什么使用热修复
1、项目中使用Tinker热修复
1.首先前往TinkerPatch平台注册账号,添加你的APP 并记下你的appkey
2、接入Tinker SDK
1、在你的项目级Gradle中添加 gradle 插件依赖
```
classpath"com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.14"
```
2、在你的app的gradle里集成 TinkerPatch SDK
```
dependencies {
// 若使用annotation需要单独引用,对于tinker的其他库都无需再引用
provided("com.tinkerpatch.tinker:tinker-android-anno:1.9.14")
compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.14")
}
```
将下面这行 Tinker 的版本号添加到 gradle.properties 文件中(Tinker的最新版本,请留意Tinker github)
TINKER_VERSION=1.7.7
注意,若使用 annotation 自动生成 Application, 需要单独引入 Tinker 的 tinker-android-anno 库。除此之外,我们无需再单独引入 tinker 的其他库。
由于TinkerPatch的相关配置有点多,为了方便我们可以新建一个tinkerpatch.gradle,并在app的gradle里引入
apply from: 'tinkerpatch.gradle',当然如果你觉得影响不大的话可以 直接写在app的gradle中
打开tinkerpatch.gradle他的配置如下
```
applyplugin:'tinkerpatch-support'
ttinkerpatchSupport {
/** 可以在debug的时候关闭 tinkerPatch **/
tinkerEnable = true
/** 是否使用一键接入功能 **/
reflectApplication = true
/** 是否开启加固模式,只有在使用加固时才能开启此开关 **/
protectedApp = false
/** 补丁是否支持新增 Activity (exported必须为false)**/
supportComponent = false
autoBackupApkPath = "${bakPath}"
/** 在tinkerpatch.com得到的appKey **/
appKey = "yourAppKey"
/** 注意: 若发布新的全量包, appVersion一定要更新 **/
appVersion = "1.0.0"
def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
def name = "${project.name}-${variantName}"
baseApkFile = "${pathPrefix}/${name}.apk"
baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
baseResourceRFile = "${pathPrefix}/${name}-R.txt"
}
**
* 用于用户在代码中判断tinkerPatch是否被使能
*/
android {
defaultConfig {
buildConfigField"boolean","TINKER_ENABLE","${tinkerpatchSupport.tinkerEnable}"
}
}
**
* 一般来说,我们无需对下面的参数做任何的修改
* 对于各参数的详细介绍请参考:
* https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
*/
tinkerPatch {
ignoreWarning =false
useSign =true
dex {
dexMode ="jar"
pattern = ["classes*.dex"]
loader = []
}
lib {
pattern = ["lib/*/*.so"]
}
res {
pattern = ["res/*","r/*","assets/*","resources.arsc","AndroidManifest.xml"]
ignoreChange = []
largeModSize =100
}
packageConfig {
}
sevenZip {
zipArtifact ="com.tencent.mm:SevenZip:1.1.10"
// path = "/usr/local/bin/7za"
}
buildConfig {
keepDexApply =false
}
```
1. reflectApplication = true 的情况
当你选择的一件接入功能时,你无需为了接入而改造Application类
直接在你的Application 中的onCreate方法初始化TinkerPatch就行
```
@Override
public void onCreate() {
super.onCreate();
// 我们可以从这里获得Tinker加载过程的信息
tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
TinkerPatch.init(tinkerApplicationLike)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(3);
// 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,通过handler实现轮训的效果
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
}
```
2. reflectApplication = false 的情况
如果我们不选择一键接入功能,我们需要将Application 的逻辑移动到 ApplicationLike类中。
```
@DefaultLifeCycle(application ="com.lqr.tinker.MyApplication",// application类名。只能用字符串,这个MyApplication文件是不存在的,但可以在AndroidManifest.xml的application标签上使用(name)
flags = ShareConstants.TINKER_ENABLE_ALL,// tinkerFlags
loaderClass ="com.tencent.tinker.loader.TinkerLoader",//loaderClassName, 我们这里使用默认即可!(可不写)
loadVerifyFlag =false)//tinkerLoadVerifyFlag
public class SampleApplicationLike extends DefaultApplicationLike {
...
@Override
public void onCreate() {
super.onCreate();
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化 SDK
TinkerPatch.init(this)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(3);
// 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,通过handler实现轮训的效果
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
}
...
}
```
并在Manifest中修改application的name属性值为
注释中application的值,第一次可能会出现报红但你无需管他
如果你的TinkerPatch还有其他需求时可以参照下面详情根据你的需求添加
详细的TinkerPatch SDK的初始化接口:
```
TinkerPatch.init(tinkerApplicationLike)
//是否自动反射Library路径,无须手动加载补丁中的So文件 注意,调用在反射接口之后才能生效,你也可以使用Tinker的方式加载Library
.reflectPatchLibrary()
//向后台获取是否有补丁包更新,默认的访问间隔为3个小时,若参数为true,即每次调用都会真正的访问后台配置
//你也可以在用户登录或者APP启动等一些关键路径,使用fetchPatchUpdate(true)强制检查更新
.fetchPatchUpdate(false)
//设置访问后台补丁包更新配置的时间间隔,默认为3个小时
.setFetchPatchIntervalByHours(3)
//向后台获得动态配置,默认的访问间隔为3个小时
//若参数为true,即每次调用都会真正的访问后台配置
.fetchDynamicConfig(new ConfigRequestCallback() {
@Override public void onSuccess(HashMap
@Override public void onFail(Exception e) { }
}, false)
//设置访问后台动态配置的时间间隔,默认为3个小时
.setFetchDynamicConfigIntervalByHours(3)
//设置当前渠道号,对于某些渠道我们可能会想屏蔽补丁功能;设置渠道后,我们就可以使用后台的条件控制渠道更新
.setAppChannel("default")
//屏蔽部分渠道的补丁功能
.addIgnoreAppChannel("googleplay")
//设置tinkerpatch平台的条件下发参数
.setPatchCondition("test", "1")
//设置补丁合成成功后,锁屏重启程序,默认是等应用自然重启
.setPatchRestartOnSrceenOff(true)
//我们可以通过ResultCallBack设置对合成后的回调,例如弹框什么
.setPatchResultCallback(new ResultCallBack() {
@Override public void onPatchResult(PatchResult patchResult) {
Log.i(TAG, "onPatchResult callback here");
}
})
//设置收到后台回退要求时,锁屏清除补丁,默认是等主进程重启时自动清除
.setPatchRollbackOnScreenOff(true)
//我们可以通过RollbackCallBack设置对回退时的回调
.setPatchRollBackCallback(new RollbackCallBack() {
@Override public void onPatchRollback() {
Log.i(TAG, "onPatchRollback callback here");
}
});
```
3、测试Tinker补丁
1、生成基包
开发完后打开AS右侧的Gradle
双击 assembleDebug(测试版)或者 assembleRelease(正式版)点击运行后会在app的build文件下产生一个bakApk
其中生成的apk文件就是我们需要的基包把他放到手机上安装
2、生成补丁
将tinkerpatch.gradle中的 baseApkFile,baseResourceRFile,baseProguardMappingFile(debug不需要,没有mapping文件)路径修改成刚生成对应的文件路径
双击tinkerPatchDebug或者tinkerPatchRelease(根据你生成的基包是否为测试版)
之后可以在build的outputs下找到
patch_signed_7zip.apk就是我们需要的补丁了
如果在运行的时候出现not found values_backup 报错 ...先备份基包生成的文件在clean你的项目把备份的文件复制到原来的路径就好
把patch_signed_7zip.apk放到我们加载方法的路径中打开app加载补丁后重启app
注意事项
最新Tinker支持新增Activity,需要tinkerpatch.gradle修改supportComponent = true,并且新增Activity的exported属性必须为false
修复补丁之后必须冷启动才能生效
Tinker对于Android N版本存在兼容性问题
对于使用assemble方式生成基包,尽量选择关闭Instant run方式编译
具体更多接入细节请参考Tinker接入文档