Android热更新集成微信Tinker
为什么选择Tinker,因为有微信在使用它,所以值得信赖。
废话不多说,上图比较目前各大热修复框架的优缺点:

我的集成是基于Tinker 1.9.8的。采用的集成方式是gradle,并且这也是官方推荐的集成方式。其实官方还提供了一种基于CDN分发的补丁管理后台,它提供了脚本后台托管,版本管理,保证传输安全等功能,可以无需搭建一个后台,无需关心部署操作,只需引入一个 SDK 即可立即使用 Tinker。但是这中唯一的缺点就是收费的,但是集成很简单,属于傻瓜式接入。
集成tinker有三个地方需要做处理:
1.项目的build.gradle
2.主module的build.gradle
3.集成Application的类
需要改变的地方我会谈到,如果不需要改变的地方,我可能会略过。我们开始来慢慢看。
首先需要添加gradle依赖,在项目的build中添加:
buildscript {
dependencies { classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1') }
}
第二步主要就是在app的build中做操作了,这边需要添加的数据稍微有点多。很多人在做这一步的时候,喜欢将demo中的gradle.build中的内容复制过来,但是我还是喜欢一点一点的复制,这样的话对app中gradle.build的内容结构心里都有个大概的认识,后面再理解起来也快很多。
在我们第一次运行demo的时候,会报一个异常,具体什么异常我忘记了,原因是tinkerId没有指定,demo里面主动抛出的异常。所以在我们复制之后,需要将gitSha()方法里面的返回内容改变一下,并且javaVersion这个字段要为java7,因为Tinker的版本支持到java7,其实你写成java8也是可以用的。

TinkerId一般我们跟app的版本号相对应,因为一个app的版本所对应的TinkerId应该是唯一的,在我们打补丁的时候,一个补丁对应的需要修补的版本号其实就是由TinkerId来决定的,并且我们可以对同一个app版本做多次的补丁修复,这个下面再说。
需要说到的还有defaultConfig中的内容:

applicationId 就是你的包名,这应该不用讲。还有一个重点就是,multiDexEnabled这个属性必须设置为true,因为使用Tinker必须要分包,这个等会在Application类还需要写。defaultConfig中其它的不需要改变,直接复制就可以。
如果需要在打签名补丁的时候,还需要设置你的签名文件:

设置buildTypes:

在设置buildTypes的时候,还有一点小坑。就是在你打debug版本的补丁的时候是成功的,但是等你打release版本的补丁的时候,可能就会失败,在你复制demo里面的buildTypes后,其实还需要去AS里面生成一下(或者直接去as里面生成),注意as设置之前需要设置signConfigs。点击Build->Edit Build Types进入:

在这里选择release,然后跳转到Build Types选项。

再有一个需要更改的地方就是:

说到这里想起来,Tinker是不支持Instant Run的,所以在使用Tinker的时候需要关闭该功能,或者将tinkerEnabled设为false。当我们集成好了Tinker之后,我们每次编译都会在Build目录下的bakApk目录生成对应的apk文件,到时候我们打的补丁需要将上面的tinkerOldApkPath跟tinkerApplyResourcePath路径替换成手机上当前的版本。所以,当我们编译好一个安装包之后,我们需要保存这两个路径的文件(要是忘记了到时候可能就尴尬了。。)。
我们还需要将ignoreWarning设为true。官方的解释是:
如果出现以下的情况,并且ignoreWarning为false,我们将中断编译。因为这些情况可能会导致编译出来的patch包带来风险:1. minSdkVersion小于14,但是dexMode的值为"raw";2. 新编译的安装包出现新增的四大组件(Activity, BroadcastReceiver...);3. 定义在dex.loader用于加载补丁的类不在main dex中;4. 定义在dex.loader用于加载补丁的类出现修改;5. resources.arsc改变,但没有使用applyResourceMapping编译。

再一个比较重要的就是loader属性:

将你不想被Tinker改变的类都加到这里面来,集成自Application的类最好也加进来。
demo里面有加sourceSets,能不加就不加把,加了可能报错。

最后就是补丁版本号的管理,那些渠道配置什么的不提也罢。

要实现上面的一个app版本打多个补丁就要靠patchVersion补丁号来决定。我们第一次的打补丁的时候,因为app上之前没有补丁,所以这边设置为1,后面如果需要再次打补丁则更改为其他数值,一般以数字递增。
最后就是添加依赖:

最后一个步骤,我们来更改Application类。

这里需要注意两点,我们继承的是DefaultApplicationLike类,并且上面@DefaultLifeCycle(application ="")中的全类名后面的BaseApplication是自己自定义的,我们发现它跟集成DefaultApplicationLike的名称不一样,并且BaseApplication需要写到清单文件中。

因为该文件暂时不存在,所以会报红,不过没关系,等会编译一下就好了。我们还需要实现两个方法:

需要再OnBaseContextAttached方法中加载MultiDex,并且初始化Tinker。我们自己的代码可以放在onCreate方法中,就像平常一样。