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代码如下:
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
over~~
更多Tinker源码解析的文章请参考:
- Android热更新开源项目Tinker源码解析系列之一:Dex热更新
- Android热更新开源项目Tinker源码解析系列之二:资源热更新
- Android热更新开源项目Tinker源码解析系类之三:so热更新
- 转载请标明本文来源:http://www.cnblogs.com/yyangblog/p/6268818.html
- 更多内容欢迎star作者的github:https://github.com/LaurenceYang/article
如果发现本文有什么问题和任何建议,也随时欢迎交流~
Android热更新开源项目Tinker集成实践总结的更多相关文章
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- Android热修复之微信Tinker使用初探
文章地址:Android热修复之微信Tinker使用初探 前几天,万众期待的微信团队的Android热修复框架tinker终于在GitHub上开源了. 地址:https://github.com/ ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
- GitHub上最著名的Android播放器开源项目大全
GitHub上最著名的Android播放器开源项目大全 ...
- Android 上传开源项目到 jcenter 实战踩坑之路
本文微信公众号「AndroidTraveler」首发. 背景 其实 Android 上传开源项目到 jcenter 并不是一件新鲜事,网上也有很多文章. 包括我本人在将开源项目上传到 jcenter ...
- android 热更新 tinker 从零开始到使用
这几天项目完结了,闲来无事,想起来了以前研究的热更新,那个开源的只有nvwa.recoo,等,不是很好用,最近听说tinker开源一段时间了,用的人还挺多,决定研究一下! 首先进入了官方文档 http ...
- Android热更新技术——Tinker、nuwa、AndFix、Dexposed
一.热修复技术作用 线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题 二.局限性与适用场景 补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大: 补丁不能支持所有的修改, ...
随机推荐
- ARM Cortex M3系列GPIO口介绍(工作方式探讨)
一.Cortex M3的GPIO口特性 在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图 从图中可以看出 ...
- 给java中的System.getProperty添加新的key value对
由于系统被格了,所以,现在的java项目配置不对,代码里面的配置类调用了一个System.getProperty("env")发现找不到该变量的值,以前一直能找到的. 其实就是以前 ...
- ZOJ-2112-Dynamic Rankings(线段树套splay树)
题意: 完成两个操作: 1.询问一个区间里第k小的数: 2.修改数列中一个数的值. 分析: 线段树套平衡树,线段树中的每个节点都有一棵平衡树,维护线段树所记录的这个区间的元素.这样处理空间上是O(nl ...
- -_-#【jQuery插件】Spinner 数字选择器
Spinner (jQuery UI)
- android webview无法加载网页
主要原因是没有在AndroidManifest.xml里面设置如下: <user-permission android:name="android.permission.INTERNE ...
- 简单约瑟夫环的循环单链表实现(C++)
刚刚接触C++以及数据结构,今天做了第一次尝试用C++和数据结构解决问题,问题是基于约瑟夫环问题的简单版. 先来看看约瑟夫环问题的介绍: 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3.. ...
- 布隆过滤器的java实现
package com.kaikeba.data.jobspider.util; import java.util.BitSet; public class Bloomfilter { private ...
- js中正则表达式的使用
1,作用:匹配一个字符串中的一些内容2,声明和使用: 1),构造函数 var reg=new RegExp(/表达式/) 2),字面量 var reg=/表达式/ 推荐使用 eg: var reg=/ ...
- JVM调优之jstack找出发生死锁的线程
1.执行死锁程序 2.执行 jstack -l 21733 | more 结果如下: 死锁程序: public static void main(String[] args) { // TODO Au ...
- PyCharm4注册码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 name : newasp == ...