• 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的内容。具体关于packer-ng-plugin的介绍,可以参考文档[Android打包工具packer-ng-plugin]。

     

    考虑三:资源混淆所造成的问题

    目前项目使用了资源混淆项目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代码如下:

     1 android.applicationVariants.all { variant ->
     2 /**
     3 * task type, you want to bak
     4 */
     5 def taskName = variant.name
     6 
     7 tasks.all {
     8 if (variant.buildType.name == 'release') {
     9 
    10 if ("tinkerPatch${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
    11 
    12 // find resguard task
    13 def resguardTask
    14 tasks.all {
    15 if (it.name.startsWith("resguard")) {
    16 resguardTask = it
    17 }
    18 }
    19 it.doFirst({
    20 // change build apk path
    21 it.buildApkPath = "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/${project.getName()}-${taskName}_signed.apk"
    22 })
    23 
    24 // change task dependence to resguard task
    25 it.dependsOn resguardTask
    26 }
    27 
    28 if ("resguard${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
    29 it.doLast {
    30 copy {
    31 def date = new Date().format("MMdd-HH-mm-ss")
    32 from "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/${project.getName()}-${taskName}_signed_7zip_aligned.apk"
    33 into file(bakPath.absolutePath + "/resguard")
    34 rename { String fileName ->
    35 fileName.replace("${project.getName()}-${taskName}_signed_7zip_aligned.apk", "${project.getName()}-${taskName}-${date}.apk")
    36 }
    37 
    38 from "${buildDir}/outputs/mapping/${taskName}/mapping.txt"
    39 into file(bakPath.absolutePath + "/resguard")
    40 rename { String fileName ->
    41 fileName.replace("mapping.txt", "${project.getName()}-${taskName}-${date}-mapping.txt")
    42 }
    43 
    44 from "${buildDir}/intermediates/symbols/${taskName}/R.txt"
    45 into file(bakPath.absolutePath + "/resguard")
    46 rename { String fileName ->
    47 fileName.replace("R.txt", "${project.getName()}-${taskName}-${date}-R.txt")
    48 }
    49 from "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/resource_mapping_${project.getName()}-release.txt"
    50 into file(bakPath.absolutePath + "/resguard")
    51 rename { String fileName ->
    52 fileName.replace("resource_mapping_${project.getName()}-release.txt", "${project.getName()}-${taskName}-${date}-resource_mapping.txt")
    53 }
    54 }
    55 }
    56 }
    57 }
    58 }

    针对问题2、在AS中使用apkRelease任务打包的方式不再适用,可直接使用packer-ng所提供的命令行方式进行生成渠道包,经过测试,100个渠道包的确在10s左右就能打完,速度相当之快。考虑到市场推广人员会打不同渠道包,后期可做一个简易工具提供给市场推广人员。

    整合后操作:


    编译:

    ./gradlew resguardRelease

    生成的apk文件放在${app}uildakApk esguard目录下


    打补丁包:

    ./gradlew tinkerPatchRelease
    ./gradlew generateManifestForReleaseTinkerPatch

    最终生成的补丁放在${app}uildoutputspatch目录下

    多渠道打包:
    针对编译后生成的包,使用packer-ng提供的命令行操作即可

    java -jar PackerNg-x.x.x.jar apkFile marketFile outputDir

    over~~

    更多Tinker源码解析的文章请参考:

     

     

  • 相关阅读:
    使用HtmlAgilityPack将HtmlTable填入DataTable
    用EXCEL的VBA将PHPCMS的备份文件转换成HTML的一次尝试
    从微观角度看到宏观世界
    洛克菲特:如何管好你的钱包
    论永生_基因编辑
    如何隐藏自己的应用程序在服务器上不被发现?
    检视阅读
    改变了我对英语理解的语法课
    Rick And Morty使命必达与毁灭--------英语笔记
    文件太大,网速太慢,如何高效的传递到服务器上运行
  • 原文地址:https://www.cnblogs.com/yyangblog/p/6268818.html
Copyright © 2020-2023  润新知