花了些时间试验了一下Tinker和TinkerPatch,总结一下。
首先吐槽 Tinker 的官方文档和github上的技术支持,真是差,Issue列表里面回复的也极不负责任。
TinkerPatch提供了和Tinker完全不同的集成方式,集成它和集成Tinker是替换关系而不是依赖关系。
集成TinkerPatch会比直接集成Tinker简单许多,并且支持patch下发。
Tinker集成要点:
- 需要将官方gradle里的内容复制到自己app的gradle里面,包括gitSha(),ext{...}等所有内容
implementation("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }
annotationProcessor("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
compileOnly("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
在gradle.properties里面加入TINKER_VERSION=x.x.x
在build.gradle中加入classpath "com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}"
- 将自己的SampleApplication 改为继承DefaultApplicationLike,同时保留sample和自己原先application中的代码。
把 @DefaultLifeCycle(application = "com.xxx.main.SampleApplicationLike", flags = ShareConstants.TINKER_ENABLE_ALL)
public class SampleApplication extends DefaultApplicationLike {
...
}
- 把AndroidManifest里面的SampleApplication 替换成SampleApplicationLike
- 添加升级按钮相关的代码:
+ String patchPath = Environment.getExternalStorageDirectory().getAbsolutePath()
+ + "/tinkersample/patch_signed_7zip.apk";
+ File file = new File(patchPath);
+ if (file.exists()) {
+ Log.v(TAG,"文件存在");
+ TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), patchPath);
+ } else {
+ Log.v(TAG,"文件不存在¨");
+ }
碰到过的一些问题和经验:
- 必须将应用加入后台白名单(如果有),否则tinker无法启动后台Jobservice
- 默认是用gitSha()来自动设置tinkerId,所以项目必须要有git,否则会报错“tinkerId is not set!!! ”
理论上说这里也可以手动写tinkerId,类似TinkerPatch中配置的appVersion,但我并没有实验过。
TinkerPatch集成要点:
- 只需要引入TinkerPatch到gradle,不需要上面所说tinker的gradle,是完全不同的接入方式
// 若使用annotation需要单独引用,对于tinker的其他库都无需再引用
compileOnly("com.tinkerpatch.tinker:tinker-android-anno:1.9.5")
implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.5")
- git clone tinkerpatch-sdk: https://github.com/TinkerPatch/tinkerpatch-sdk
- 将tinkerpatch-sdk的作为gradle导入,命名为tinkerpatch.gradle,并在app的build.gradle中引入
apply from: 'tinkerpatch.gradle'
- 可以设置 reflectApplication = true 则不需要改动application,否则参考上面Tinker步骤改造application
- 生成patch前,需要修改versionCode, versionName,以及tinkerpatch.gradle中的appVersion(即versionName)
碰到过的一些问题和经验:
- 必须将应用加入后台白名单(如果有),否则tinker无法启动后台Jobservice
- 编译方式(debug/release)和应用的签名一定要统一,设置useSign = true
如果编译debug apk,使用gradlew.bat tinkerPatchDebug命令生成patch_signed_7zip.apk上传服务器
如果编辑release apk,先要配置好签名文件再执行gradlew.bat tinkerPatchRelease 命令生成patch_signed_7zip.apk上传服务器
参考https://blog.csdn.net/qq_26589227/article/details/78287707 - 对于正式版本及其中间文件要妥善保存
一些参考
https://juejin.im/post/5838298d61ff4b006b442b53
https://blog.csdn.net/qq_26589227/article/details/78287707 --- 如何配置签名
https://blog.csdn.net/y97524027/article/details/52690077 -- 关于git命令“git rev-parse --short HEAD”