第六章 Android动态加载、热更新、热修复、插件化系列文章 之 Tinker介绍

本文是关于Android热更新解决方案Tinker的集成教程,包括在项目中添加依赖、配置Gradle脚本、改造Application、生成差异包等步骤。Tinker支持动态下发代码、So库和资源,广泛应用于修复和功能更新。文章还提到了Tinker与其他热修复方案的对比,以及在Android N上的性能影响和已知问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第五章 android热更新系列文章 之 Tinker 介绍





目录

1. 概述 - Tinker的基本介绍

2. 完整的demo下载,快速体验

3. Tinker官方开源项目链接

4. 为什么使用Tinker

5. Tinker的缺陷及不足

6. AndroidStudio gradle构建脚本下的Tinker集成

  6.1 集成tinker的环境要求

  6.2 Tinker 的集成步骤

7. apkPatch 补丁包文件实际生产环境中的下载和安装解决方案

8. 总结了一些常见问题,你很可能会遇到,不要紧张可以看看下面有对应的解决方案没

  8.1 通过AndroidStudio方式生成差异包的时候如果不小心修改了XML会报下面的错误

  8.2 生成差异包时报错:Warning:ignoreWarning is false, but we found loader classes are found in old secondary dex. Found classes:

  8.3 生成差异包时尝试更改 AndroidManifest 清单文件,出现编译期报错




1. 概述 - Tinker的基本介绍

Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。当然,你也可以使用Tinker来更新你的插件。

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

gradle编译插件: tinker-patch-gradle-plugin
核心sdk库: tinker-android-lib
非gradle编译用户的命令行版本: tinker-patch-cli.jar

Tinker是由腾讯推出的一款支持dex、依赖库、资源文件,清单文件更新的android热修复解决方案,使用tinker可以解决发版本完成版本更新,和阿里系的Andfix相比tinker的使用场景法更为广(包括了dex、依赖库、资源文件,清单文件),修复的成功率更高,听起来是不是很炫酷,




2. 完整的demo下载,快速体验
附完整的demo链接 : https://github.com/benchegnzhou/TinkerDemo



3. Tinker官方开源项目链接
Tinker官方开源项目链接 : https://github.com/Tencent/tinker/



4. 为什么使用Tinker

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

比较项 Tinker QZone AndFix Robust
类替换 yes yes no no
So替换 yes no no no
资源替换 yes yes no no
全平台支持 yes yes yes yes
即时生效 no no yes yes
性能损耗 较小 较大 较小 较小
补丁包大小 较小 较大 一般 一般
开发透明 yes yes no no
复杂度 较低 较低 复杂 复杂
gradle支持 yes no no no
Rom体积 较大 较小 较小 较小
成功率 较高 较高 一般 最高

总的来说:

AndFix作为native解决方案,首先面临的是稳定性与兼容性问题,更重要的是它无法实现类替换,它是需要大量额外的开发成本的;
Robust兼容性与成功率较高,但是它与AndFix一样,无法新增变量与类只能用做的bugFix方案;
Qzone方案可以做到发布产品功能,但是它主要问题是插桩带来Dalvik的性能问题,以及为了解决Art下内存地址问题而导致补丁包急速增大的。
特别是在Android N之后,由于混合编译的inline策略修改,对于市面上的各种方案都不太容易解决。而Tinker热补丁方案不仅支持类、So以及资源的替换,它还是2.X-8.X(1.9.0以上支持8.X)的全平台支持。利用Tinker我们不仅可以用做bugfix,甚至可以替代功能的发布。Tinker已运行在微信的数亿Android设备上,那么为什么你不使用Tinker呢?




5. Tinker的缺陷及不足

Tinker的确非常的强大,但是也不是没有局限性的,比如不支持XML文件的修改就显得十分的鸡肋了,同时也无法修改APP的图标和APP的名称(这对于一个APP的节日营销是致命的存在),同时还存在以下已知的问题

Tinker的已知问题

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

Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
在Android N上,补丁对应用启动时间有轻微的影响;
不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。

在当前流行的热更新框架中tinker可以说是功能最为齐全的(
可以完成方法替换、类替换、类结构以及资源的修改、so替换、jar文件替换,可以完美支持全平台),最主要的是可以完美的结合gradle构建工具使用生成差异包。怎么样,我们仅仅说最后一条,你是不是就已经心动了。以为我们只要集成完成一次,剩下的事情就是简单的调一下参数这么简单了。

这里强调几点,我们选择开源框架的几个原则

  1. 看公司的项目需求,满足公司项目需求这是必要的一步,这里说的满足,并不一定要完全的超预期还要符合下面的几点要求。
  2. 尽量选择大厂并且项目有专门团队在维护,而且最近一直在维护。(因为不断的维护,这样可以减小入坑的机会同时受众广,框架会得到很好的验证)
  3. 尽量选择学习成本较低的一个。(这种一般选择文档清晰,使用受众广的出了问题方便排查)

tinker 是腾讯大厂的一个成熟的开源项目,在github上有自己的维护地址:https://github.com/Tencent/tinker 项目目前14k star 足可见还是让开发者普遍接受的。




6. AndroidStudio gradle构建脚本下的Tinker集成


6.1 集成tinker的环境要求

集成环境要求 Android studio 3.1.1 及其以上




6.2 Tinker 的集成步骤
6.2.1 在工程项目的根目录中的build.gradle添加 tinker-gradle-plugin 作为项目的依赖
classpath("com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}") {
            changing = TINKER_VERSION?.endsWith("-SNAPSHOT")
            exclude group: 'com.android.tools.build', module: 'gradle'
}
6.2.2 在项目moudle的 app/build.gradle 中,添加如下依赖
 	//方法过多google提供的分包解决方案   参考 https://yq.aliyun.com/articles/12429   和  http://blog.csdn.net/gulihui890411/article/details/48551551
    implementation 'com.android.support:multidex:1.0.3'

    //optional, help to generate the final application
    compileOnly("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
    //tinker's main Android lib
    implementation("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }

    // Maven local cannot handle transist dependencies.
    implementation("com.tencent.tinker:tinker-android-loader:${TINKER_VERSION}") { changing = true }

    annotationProcessor("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") {
        changing = true
    }
6.2.3 在 gradle.properties 文件中配置 TINKER_VERSION 变量,统一指定依赖库和plugin的版本号

gradle.properties 文件中添加 TINKER_VERSION=1.9.1,(gradle.properties 文件在根项目的 build.gradle 同级目录,没有同学请自行创建) ,这里我们以 1.9.1 版本为例。

注: 依赖库和plugin版本号不一致会导致编译出现异常,请慎重检查

6.2.4 同步一下项目工程
6.2.5 创建 CustomApplicationLike 继承 ApplicationLike,编译后,Tinkerplugin会自动帮我们创建自定义名称的 MApplication 对象继成自 TinkerApplication(这个Application相当于我们以前的自定义Application)

通过注解关键字 DefaultLifeCycle 指定参数,application 对应要生成的自定义 application 名称和位置(比如我们指定为MApplication ,同步一下代码就会在build文件夹下看到生成的 MApplication 对象),默认是和 CustomApplicationLike 在同一个包中,参数 flags 可以指定动态更新的范围,默认的取值

  • 注解参数说明
取值 默认值 描述 备注
application null gradle脚本生成自定义 application 的位置和名称
flags TINKER_DISABLE 更新增量包加载类型标识位 tinker运行时支持的补丁包中的文件类型:
1. ShareConstants.TINKER_DISABLE:不支持任何类型的文件;
2. ShareConstants.TINKER_DEX_ONLY:只支持dex文件;
3. ShareConstants.TINKER_LIBRARY_ONLY:只支持library文件;
4. ShareConstants.TINKER_DEX_AND_LIBRARY:只支持dex与res的修改;
5. ShareConstants.TINKER_ENABLE_ALL:支持任何类型的文件,也是我们通常的设置的模式。
loadVerifyFlag 更新增量包校验标识位
  • flags 的取值和含义
参数名称 描述 备注
TINKER_DISABLE 不支持任何类型的文件
TINKER_DEX_MASK 只支持dex文件
TINKER_NATIVE_LIBRARY_MASK 只支持library文件
TINKER_RESOURCE_MASK 只支持resource文件
TINKER_DEX_AND_LIBRARY 只支持dex与res的修改
TINKER_ENABLE_ALL 支持任何类型的文件,也是我们通常的设置的模式
	@DefaultLifeCycle(application = ".MApplication"
	        , flags = ShareConstants.TINKER_ENABLE_ALL  
	        , loadVerifyFlag = false)
	public class CustomApplicationLike extends ApplicationLike {
	
	
	    public static Context sApplication;
	    public static CustomApplicationLike sApplike;
	
	
	    public CustomApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
	        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
	    }
	
	    @Override
	    public void onBaseContextAttached(Context base) {
	        super.onBaseContextAttached(base);
	        //使应用支持分包
	        MultiDex.install(base);
	
	
	        SampleApplicationContext.application = getApplication();
	        SampleApplicationContext.context = getApplication();
	        TinkerManager.setTinkerApplicationLike(this);
	
	        TinkerManager.initFastCrashProtect();
	        //should set before tinker is installed
	        TinkerManager.setUpgradeRetryEnable(true);
	
	        //optional set logIml, or you can use default debug log
	        //TinkerInstaller.setLogIml(new MyLogImp());
	
	        //installTinker after load multiDex
	        //or you can put com.tencent.tinker.** to main dex
	        TinkerManager.installTinker(this);
	        Tinker tinker = Tinker.with(getApplication());
	
	        //获取全局上下文
	        sApplication = base;
	        sApplike = this;
	
	
	        CommonUtil.getInstance().init(base, new Config()
	                .setLogOpen(true)
	                .setLogTag("ZBC_TINKER")
	                .setToastOpen(true));
	    }
	
	
	
	
	    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
	    public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
	        getApplication().registerActivityLifecycleCallbacks(callback);
	    }
	
	}

更新后看到tinker为我们代码生成的 MApplication

6.2.6 需要在 AndroidManifest.xml 文件中配置这个Application的名称需要和 CustomApplicationLike 类的注解一直
6.2.7 改造项目原有的Appalication

这个分两种情况

  1. 我们的项目原来已经有自己的 MApplication 继承系统的 Application,这时候我们应该把 application 中的代码移植到自己创建的 SampleApplicationLike 类,这个类继承自 ApplicationLike,建议将例如:

     @DefaultLifeCycle(application = ".MApplication"                     //application类名
     	, flags = ShareConstants.TINKER_ENABLE_ALL                 		//tinkerFlags
     	, loadVerifyFlag = false)                                   	//tinkerLoadVerifyFlag
     public class CustomApplicationLike extends ApplicationLike {
     
     
         public static Context sApplication;
         public static CustomApplicationLike sApplike;
     
     
         public CustomApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMilli
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值