Android热更新开源项目Tinker集成实践总结
前言
最近项目集成了tinker,开始认为集成会比较简单,但是在实际操作的过程中还是遇到了一些问题,本文就会介绍在集成过程大家基本会遇到的主要问题。
考虑一:后台的选取
目前后台功能可以通过三种方式实现:
1、自己搭建后台布丁下发系统
2、第三方提供的服务,目前如原微信simsun大神的个人tinkerpatch平台,目前出于内测阶段,暂时免费。后期应该会按下发量对app进行收费。
3、腾讯bugly提供的服务,提供了热更新的下发后台,集成到了bugly的升级sdk中。免费。
根据公司的精神,我们选择了bugly作为我们的方案,这个大家都懂得。
考虑二:多渠道打包的问题
我们有将近100个渠道,每个渠道需要一个不同的渠道号,按product flavor的方式打出来的包的dex都有差异。这样就造成100个渠道包的热更新就需要100个补丁,这对管理简直是一个灾难。tinker也对这种问题给出了推荐的方案,那就是使用开源项目packer-ng-plugin,它的原理是将渠道信息写在apk文件的zip comment中,这样在多渠道打包时就不会影响dex的内容。
考虑三:资源混淆所造成的问题
目前项目使用了资源混淆项目andresguard,关于andresguard的介绍,可以参考文档andresguard[android混淆工具andresguard]。
也正是引入了资源混淆,热更新和多渠道打包都必须依赖资源混淆后生成的apk包才行。所以我们对编译流程进行了整合。
**整合前**
编译:编译直接使用andresguard提供的命令resguardrelease生成即可。resguardrelease生成的apk文件是没有资源混淆的。
./gradlew resguardrelease
tinker生成补丁:直接调用tinkerpatchrelease任务生成的release文件没有进行资源混淆
./gradlew tinkerpatchrelease
多渠道打包:使用packer-ng的命令apkrelease生成多渠道文件没有进行资源混淆
./gradlew apkrelease
**整合后**
主要解决两个问题:
1、tinker生成补丁的原始和新的apk,需要使用资源混淆后的apk
2、多渠道打包所使用的原始apk,需要使用资源混淆后的apk
针对问题1:
当使用resguardrelease进行编译,在编译完成后,将生成的apk文件、r文件、map文件和resouce map文件拷贝到${builddir}/bakapk/resguard目录下;
当使用tinkerpatchrelease生成补丁时,在tinkerpatchrelease任务前加入resguardtask任务,这样生成补丁时使用的新旧apk都是资源混淆过的。核心的gradle代码如下:
android.applicationvariants.all { variant -> /** * task type, you want to bak */ def taskname = variant.name tasks.all { if (variant.buildtype.name == 'release') { if ("tinkerpatch${taskname.capitalize()}".equalsignorecase(it.name)) { // find resguard task def resguardtask tasks.all { if (it.name.startswith("resguard")) { resguardtask = it } } it.dofirst({ // change build apk path it.buildapkpath = "${builddir}/outputs/apk/andresguard_${project.getname()}-${taskname}/${project.getname()}-${taskname}_signed.apk" }) // change task dependence to resguard task it.dependson resguardtask } if ("resguard${taskname.capitalize()}".equalsignorecase(it.name)) { it.dolast { copy { def date = new date().format("mmdd-hh-mm-ss") from "${builddir}/outputs/apk/andresguard_${project.getname()}-${taskname}/${project.getname()}-${taskname}_signed_7zip_aligned.apk" into file(bakpath.absolutepath + "/resguard") rename { string filename -> filename.replace("${project.getname()}-${taskname}_signed_7zip_aligned.apk", "${project.getname()}-${taskname}-${date}.apk") } from "${builddir}/outputs/mapping/${taskname}/mapping.txt" into file(bakpath.absolutepath + "/resguard") rename { string filename -> filename.replace("mapping.txt", "${project.getname()}-${taskname}-${date}-mapping.txt") } from "${builddir}/intermediates/symbols/${taskname}/r.txt" into file(bakpath.absolutepath + "/resguard") rename { string filename -> filename.replace("r.txt", "${project.getname()}-${taskname}-${date}-r.txt") } from "${builddir}/outputs/apk/andresguard_${project.getname()}-${taskname}/resource_mapping_${project.getname()}-release.txt" into file(bakpath.absolutepath + "/resguard") rename { string filename -> filename.replace("resource_mapping_${project.getname()}-release.txt", "${project.getname()}-${taskname}-${date}-resource_mapping.txt") } } } } } }
针对问题2、在as中使用apkrelease任务打包的方式不再适用,可直接使用packer-ng所提供的命令行方式进行生成渠道包,经过测试,100个渠道包的确在10s左右就能打完,速度相当之快。考虑到市场推广人员会打不同渠道包,后期可做一个简易工具提供给市场推广人员。
整合后操作:
编译:
./gradlew resguardrelease
生成的apk文件放在${app}\build\bakapk\resguard\目录下
打补丁包:
./gradlew tinkerpatchrelease ./gradlew generatemanifestforreleasetinkerpatch
最终生成的补丁放在${app}\build\outputs\patch\目录下
多渠道打包:
针对编译后生成的包,使用packer-ng提供的命令行操作即可
java -jar packerng-x.x.x.jar apkfile marketfile outputdir
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
上一篇: 分别用ToolBar和自定义导航栏实现沉浸式状态栏
下一篇: 图片格式判断