移动端热修复方案-Tencent tinker

时间:2021-07-28 20:07:48

热修复方案概述

1.QQ空间热修复方案

RocooFix

Nuwa

HotFix

2.native hook的方案

AndFix

阿里百川(未开源)

3.微信热修复方案

4.手机QQ热修复方案

QFix:推荐文章QFix探索之路——手Q热补丁轻量级方案

移动端热修复方案-Tencent tinker

Tinker是什么

它主要包括以下几个部分:

1.gradle编译插件: tinker-patch-gradle-plugin

2.核心sdk库: tinker-android-lib

3.非gradle编译用户的命令行版本: tinker-patch-cli.jar

为什么使用Tinker

当前市面的热补丁方案有很多,其中比较出名的有阿里的AndFix、美团的Robust以及QZone的超级补丁方案。但它们都存在无法解决的问题,这也是正是我们推出Tinker的原因。

移动端热修复方案-Tencent tinker

各个Hotfix方案对比总的来说:

1.AndFix作为native解决方案,首先面临的是稳定性与兼容性问题,更重要的是它无法实现类替换,它是需要大量额外的开发成本的;

2.Robust兼容性与成功率较高,但是它与AndFix一样,无法新增变量与类只能用做的bugFix方案;

3.Qzone方案可以做到发布产品功能,但是它主要问题是插桩带来Dalvik的性能问题,以及为了解决Art下内存地址问题而导致补丁包急速增大的。特别是在Android N之后,由于混合编译的inline策略修改,对于市面上的各种方案都不太容易解决。

而Tinker热补丁方案不仅支持类、So以及资源的替换,它还是2.X-7.X的全平台支持。利用Tinker我们不仅可以用做bugfix,甚至可以替代功能的发布。Tinker已运行在微信的数亿Android设备上,那么为什么你不使用Tinker呢?

Tinker的已知问题由于原理与系统限制,Tinker有以下已知问题:

a.Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件;

b.由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;

c.在Android N上,补丁对应用启动时间有轻微的影响;

d.不支持部分三星android-21机型,加载补丁时会主动抛出”TinkerRuntimeException:checkDexInstall failed”;

e.由于各个厂商的加固实现并不一致,在1.7.6以及之后的版本,tinker不再支持加固的动态更新;

f.对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。

如何使用TinkerTinker

为了实现“高可用”的目标,在接入成本上做了妥协。热补丁并不简单,在使用之前请务必先仔细阅读以下文档:

如何快速接入请参考Tinker 接入指南;

如何自定义类请参考Tinker 自定义扩展;

Tinker的API预览请参考Tinker API预览;

其他常见问题,请参考常见问题;

TinkerPatch后台

补丁平台支持一键傻瓜式接入,使用请参考TinkerPatch平台文档。

Tinker 接入指南

gradle接入

gradle是推荐的接入方式,在gradle插件tinker-patch-gradle-plugin中我们帮你完成proguard、multiDex以及Manifest处理等工作。

1.添加gradle依赖

在项目的build.gradle中,添加tinker-patch-gradle-plugin的依赖

然后在app的gradle文件app/build.gradle,我们需要添加tinker的库依赖以及apply tinker的gradle插件.

dependencies {

//可选,用于生成application类

//tinker的核心库

......

//apply tinker插件

apply plugin: 'com.tencent.tinker.patch'gradle

参数详解

我们将原apk包称为基准apk包,tinkerPatch直接使用基准apk包与新编译出来的apk包做差异,得到最终的补丁包。

这个地方,对比官方文档和官方提供的demo来学习时,很明显感觉到比较繁琐,但为了严谨和后面维护少出问题,还是请大家仔细阅读和详细分析官方demo的配置步骤;

tinkerPatch task详解

直接使用

task:tinkerPatchVariantName(例如tinkerPatchDebug、tinkerPatchRelease)

即可自动根据Variant选择相应的编译类型,同时它还贴心的为我们完成以下几个操作:将TINKER_ID自动插入AndroidManifest的meta项,输出路径为build/intermediates/tinker_intermediates/AndroidManifest.xml;

如果minifyEnabled为true,将自动将Tinker的proguard规则添加到proguardFiles中,输出路径为build/intermediates/tinker_intermediates/tinker_proguard.pro,这里你不需要将它们拷贝到自己的proguard配置文件中;如果multiDexEnabled为true,将自动生成Tinker需要放在主dex的keep规则。

在tinker 1.7.6版本之前,你需要手动将生成规则拷贝到自己的multiDexKeepProguard文件中。

例如Sample中的multiDexKeepProguard file(“keep_in_main_dex.txt”)。

在1.7.6版本之后,这里会通过脚本自动处理,无须手动填写。

把dexOptions的jumboMode打开。输出路径为:build/intermediates/tinker_intermediates/tinker_multidexkeep.pro。

然后你可以在build/outputs/tinkerPatch中找到输出的文件。

多Flavor打包有的时候我们希望通过flavor方式打包,在sample中提供了简单的用法事例:

1.通过flavor编译,这个时候我们可以看到bakApk路径是一个按照flavor名称区分的目录;

2.将编译目录路径填写到sample中tinkerBuildFlavorDirectory,其他的几个字段不需要填写,这里会自动根据路径拼接;123ext { tinkerBuildFlavorDirectory = "$/app-1014-13-35-12"}

3.运行tinkerPatchAllFlavorDebug或者tinkerPatchAllFlavorRelease即可得到所有flavor的补丁包。

输出文件详解在tinkerPatch输出目录build/outputs/tinkerPatch中,

我们关心的文件有:

文件名 描述

patch_unsigned.apk 没有签名的补丁包

patch_signed.apk 签名后的补丁包

patch_signed_7zip.apk 签名后并使用7zip压缩的补丁包,也是我们通常使用的补丁包。但正式发布的时候,最好不要以.apk结尾,防止被运营商挟持。

log.txt 在编译补丁包过程的控制台日志

dex_log.txt 在编译补丁包过程关于dex的日志

so_log.txt 在编译补丁包过程关于lib的日志

tinker_result 最终在补丁包的内容,包括diff的dex、lib以及assets下面的meta文件

resources_out.zip 最终在手机上合成的全量资源apk,你可以在这里查看是否有文件遗漏

resources_out_7z.zip 根据7zip最终在手机上合成的全量资源

apktempPatchedDexes 在Dalvik与Art平台,最终在手机上合成的完整Dex,我们可以在这里查看dex合成的产物。

每次编译结束,我们都应该查看相关日志,清楚最终在补丁包中的文件。尤其是dex的补丁文件,即使是1k的dex补丁文件,也会带来合成时的时间损耗以及合成完整dex文件ROM空间体积这两部分影响!

TinkerPatch补丁管理后台

>动手能力强的同学,可以自己按照wiki中的步骤一点一滴的逐步学习;需要提醒大家的是:如果遇到问题,提issue前一定先参考下这个Tinker-常见问题,否则,issue都不会被关注而是直接关闭的;懒得动手的话,可直接接入tinker的第三方平台,参考接入文档,有免费版和收费版两种可供选择。

坚持原创技术分享,您的支持将鼓励我继续创作!