基准包
例如有一个版本A,但是这时A是有Bug的,然后修复Bug后的生成的版本我们称为B。A和B之间的区别产生一个差分包(这里也称为补丁包),那么我们就可以说这个差分包是以A作为基准包相对B生成的。
基本步骤
1、注册Tinker账号并新建项目2、配置gradle和代码3、生成基准包4、修复Bug5、生成补丁包6、发布补丁包
Tinker做了什么
1、1-2步是APP开发的基本步骤,完成1-3步,那么你的APP就集成了Tinker。集成Tinker后,Tinker会根据各个版本的配置信息去自动加载补丁。可配置强制更新,也可配置轮询更新。
2、第3步则是保留一个之前版本副本,用于后面生成补丁。为什么要这样做?因为1.0.2的相对于1.0.1的补丁包只能作用在1.0.1版本上。如果想要处理1.0.0那么有两种方法,使用1.0.0->1.0.1和1.0.1->1.0.2两个补丁包。但是也可以生成1.0.0->1.0.2的补丁包。所以副本保留还是有必要的。3、4-6部就是真正应用到生产环境上了,真正达到热修复的作用。
一、注册Tinker账号
这个就不说了,Tinker注册和新建项目都好简单,也没有什么需要注意的。拿到appKey
二、配置Gradle和代码
这个推荐我们的拷贝粘贴代码
1、配置Tinker版本信息
我们使用配置文件去配置版本信息,易于统一版本和后面更换版本编辑根目录的gradle.properties
,加入
TINKER_VERSION=1.9.2TINKERPATCH_VERSION=1.2.2
2、配置根目录下的build.gradle文件
使用Tinker插件
classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:${TINKERPATCH_VERSION}"
3、配置Tinker的gradle脚本
在项目根目录新建tinkerpatch.gradle
文件
apply plugin: 'tinkerpatch-support'/*** TODO: 请按自己的需求修改为适应自己工程的参数*/def bakPath = file("${buildDir}/bakApk/")def baseInfo = "app-1.0.0-1213-19-52-36"def variantName = "release"/*** 对于插件各参数的详细解析请参考* http://tinkerpatch.com/Docs/SDK*/tinkerpatchSupport { /** 可以在debug的时候关闭 tinkerPatch **/ /** 当disable tinker的时候需要添加multiDexKeepProguard和proguardFiles, * 这些配置文件本身由tinkerPatch的插件自动添加,当你disable后需要手动添加 * 你可以copy本示例中的proguardRules.pro和tinkerMultidexKeep.pro, * 需要你手动修改'tinker.sample.android.app'本示例的包名为你自己的包名, * com.xxx前缀的包名不用修改 **/ tinkerEnable = true reflectApplication = true /** * 是否开启加固模式,只能在APK将要进行加固时使用,否则会patch失败。 * 如果只在某个渠道使用了加固,可使用多flavors配置 **/ protectedApp = false /** * 实验功能 * 补丁是否支持新增 Activity (新增Activity的exported属性必须为false) **/ supportComponent = true autoBackupApkPath = "${bakPath}" appKey = "c6a00cf4aafa2ab2" /** 注意: 若发布新的全量包, appVersion一定要更新 **/ appVersion = "1.0.0" def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/" def name = "${project.name}-${variantName}" baseApkFile = "${pathPrefix}/${name}.apk" baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt" baseResourceRFile = "${pathPrefix}/${name}-R.txt" /** * 若有编译多flavors需求, 可以参照: * https://github.com/TinkerPatch/tinkerpatch-flavors-sample * 注意: 除非你不同的flavor代码是不一样的, * 不然建议采用zip comment或者文件方式生成渠道信息 * (相关工具:walle 或者 packer-ng) **/}/*** 用于用户在代码中判断tinkerPatch是否被使用*/android { defaultConfig { buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}" }}/*** 一般来说,我们无需对下面的参数做任何的修改* 对于各参数的详细介绍请参考:* https://github.com/Tencent/tinker/wiki/Tinker-* %E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97*/tinkerPatch { ignoreWarning = false useSign = true dex { dexMode = "jar" pattern = ["classes*.dex"] loader = [] } lib { pattern = ["lib/*/*.so"] } res { pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"] ignoreChange = [] largeModSize = 100 } packageConfig { } sevenZip { zipArtifact = "com.tencent.mm:SevenZip:1.1.10"// path = "/usr/local/bin/7za" } buildConfig { keepDexApply = false }}
注意几个字段内容,主要是后面生成补丁需要用到的,除了AppKey外其他暂时不用改baseInfo
: 这个是基准包的名称,使用Tinker脚本编译在模块的build/bakApk生成编译副本variantName
: 这个一般对应buildTypes
里面你基准包生成的类型,release、debug或其他appKey
:
这个就是Tinker新建项目时拿到的appKeyappVersion
: 配置和Tinker后台新建补丁包的一致
4、配置模块下的buidle.gradle
配置应用签名
这个百度搜都有,大概就这样
signingConfigs { release {//发布版本的签名配置 storeFile file('key.jks') keyAlias 'test' storePassword '123456789' keyPassword '123456789' } debug {//调试版本的签名配置 storeFile file('key.jks') keyAlias 'test' storePassword '123456789' keyPassword '123456789' } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } debug { signingConfig signingConfigs.debug } }
配置依赖
//若使用annotation需要单独引用,对于tinker的其他库都无需再引用 annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true } compileOnly("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true } implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") { changing = true }
使用插件
在模块的build.gradle加入
apply from: 'tinkerpatch.gradle'
3、代码配置
最后一步配置,把代码集成到App里,别忘了在AndroidManifest里面配置APP。。。
public class App extends Application { private ApplicationLike tinkerApplicationLike; @Override public void onCreate() { super.onCreate(); tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike(); // 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK TinkerPatch.init(tinkerApplicationLike) .reflectPatchLibrary() .fetchPatchUpdate(true) // 强制更新 .setPatchRollbackOnScreenOff(true) .setPatchRestartOnSrceenOff(true) .setFetchPatchIntervalByHours(3); // 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新, 通过handler实现轮训的效果 TinkerPatch.with().fetchPatchUpdateAndPollWithInterval(); }
三、生成基准包
其实到了这里就配置完成了,我们生产一个基准包
生成基准包
双击assembleRelease生成成功后安装模块/build/outputs/apk/release/app-release.apk
就OK了,这时候进去模块/build/bakApk
里面记录一下类似app-1.0.0-1213-19-52-36
的文件名称,只生成一次基准包,那么就会生成一个。但是如果手贱点太多生成太多的话确定不了刚刚生成的是哪个,那么就选最新那个或者删掉重新生成基准包,真实环境并不允许这样搞。。。
安装包
基准包名称
四、修复bug
随便修改点代码
五、生成补丁包
这时候我们就需要去修改一些tinkerpatch.gradle
文件的信息了。baseInfo
:还记得app-1.0.0-1213-19-52-36
这个东西吗?换成自己上面记录的就OK了variantName
: 因为刚刚我们使用assembleRelease
生成的补丁,所以我们只需要使用release
就OK了
生成差分包
双击TinkerPatchRelease
生成差分包,patch_signed_7zip.apk
就是补丁包了
补丁包
六、发布补丁包
回到Tinker后台,选中我们开始新建的项目,补丁下发->添加APP版本。然后上传刚刚的patch_signed_7zip.apk
。
发布补丁包
APP开启强制更新的话那么重启应用就会更新,否则会通过轮询去更新。应用重启才生效。Tinker太强大了,本文目的就是把项目跑通,相信后面的很多功能大家有兴趣的话一起发现,一起讨论。
作者 | August1996
地址 | https://www.jianshu.com/p/3227dfa56eac
声明 | 本文是 August1996 原创,已获授权发布,未经原作者允许请勿转载