Tinker

参考 Tinker – 微信Android热补丁方案

1. Tinker是什么。

Android热补丁解决方案,支持动态下发代码,So库以及资源,让应用在不重新安装的情况下实现更新。
主要包括:

  • gradle编译插件
  • 核心SDK库
  • 非gradle编译用户的命令行版本

2. 为什么使用Tinker。

AndFix,Robust,QZone存在无法解决的问题。而Tinker很好的解决了这些问题。

  • AndFix无法实现类替换,面临稳定性和兼容性的问题,需要大量的额外开发。
  • Robust兼容性和成功率较高,但是无法新增变量和类,暂时只能用做bugFix。
  • QZone插桩带来的dalvik性能问题以及解决ART下的内存地址问题导致补丁包急速增大的。
  • Tinker热补丁方案不仅支持类、So以及资源的替换,它还是2.X-7.X的全平台支持。利用Tinker我们不仅可以用做bugfix,甚至可以替代功能的发布。

3. Tinker已知问题

  1. Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件;
  2. 由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
  3. 在Android N上,补丁对应用启动时间有轻微的影响;
  4. 不支持部分三星android-21机型,加载补丁时会主动抛出”TinkerRuntimeException:checkDexInstall failed”;
  5. 由于各个厂商的加固实现并不一致,在1.7.6以及之后的版本,tinker不再支持加固的动态更新;
  6. 对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。

4. Tinker Demo 使用步骤详解

Sample的使用方法 Demo请参考tinker-sample-android

使用方法如下:

  1. 调用assembleDebug编译,会将编译过的包保存在build/bakApk中。然后adb install 将它安装到手机,点击SHOW INFO按钮,提示 patch is not loaded 表示 当前补丁并没有加载

  2. 修改代码,例如将MainActivity中I am on patch onCreate的Log打开。然后我们需要修改build.gradle中的参数,将步骤一编译保存的安装包路径拷贝到tinkerPatch中的oldApk参数中。

1
2
3
4
5
6
//更新bugApk 文件地址
//old apk file to build patch apk
tinkerOldApkPath = "${bakPath}/old_apk_name.apk"

//resource R.txt to build patch apk, must input if there is resource changed
tinkerApplyResourcePath = "${bakPath}/old_apk_name.txt"
  1. 调用tinkerPatchDebug, 补丁包与相关日志会保存在/build/outputs/tinkerPatch/。然后我们将patch_signed_7zip.apk推送到手机的sdcard中。
1
adb push ./app/build/outputs/tinkerPatch/debug/patch_signed_7zip.apk /storage/sdcard0/
  1. 点击LOAD PATCH按钮, 如果看到patch success, please restart process的toast,即可锁屏或者点击KILL SELF按钮

  2. 当看到的确出现了I am on patch onCreate日志,同时点击SHOW INFO按钮,显示补丁包的确已经加载成功了。

5. 源码调试

tinker调试源码时,只需在tinker的主工程运行tinker group中buildAndPublishTinkerToLocalMaven任务即可。

此外由于localmaven无法传递依赖,需要在使用的地方再显式引用以下库:

1
2
3
4
compile("com.tencent.tinker:tinker-android-loader:${TINKER_VERSION}") { changing = true }
compile("com.tencent.tinker:aosp-dexutils:${TINKER_VERSION}") { changing = true }
compile("com.tencent.tinker:bsdiff-util:${TINKER_VERSION}") { changing = true }
compile("com.tencent.tinker:tinker-commons:${TINKER_VERSION}") { changing = true }

github/Tinker的默认分支为master分支,几个含义的含义分别是:

  • master分支;最近一次release的稳定代码,我们在master分支打tag;
  • dev分支;开发分支,这里会包含下一个版本的代码,我们只能给dev分支提pr以及验证部分已经修复的issue;
  • hotfix分支;为了修复tinker紧急bug的分支。

6. TinkerPatch补丁管理后台

[www.tinkerpatch.com] (http://www.tinkerpatch.com/) 是第三方开发基于CDN分发的补丁管理后台。它提供了脚本后台托管,版本管理,保证传输安全等功能,让你无需搭建一个后台,无需关心部署操作,只需引入一个 SDK 即可立即使用 Tinker。

此外,TinkerPatch 平台增加了一键傻瓜式接入/编译管理优化等功能,它的Github地址为TinkerPatch。