Android多渠道打包性能优化V1
1、问题
传统的方式在 build.gradle 中通过 productFlavors 配置多渠道的方案,在多渠道打包时会执行多次编译打包过程,速度缓慢
网上已经有成熟的、大厂大牛写的开源项目解决该问题;比如美团的walle
但是,用第三方的插件,有时候不灵活。比如我们已经用了一个第三方打包插件,而我们多渠道打包任务要放在该插件执行完成之后;
这时候就不太好弄了。
这里简单实现多渠道快速打包
2、原理
我们的apk实际上就是个zip压缩文件;
android在7.0之前,对apk签名校验,校验的是解压后的文件,所以在zip压缩文件上改动是不需要重新签名的;
通过再apk文件末端添加zip注释内容,把渠道信息作为注释写入apk文件中;
程序中,读取apk末端注释中的内容,解析出渠道信息
3、注意要点
android 7.0之后,对apk签名校验是会校验压缩包的,通过该方法写入渠道信息后需要重新签名
解决方案:
1、在 build.gradle的 signingConfigs 中配置 v2SigningEnabled false ,则不会使用v2校验,不需要重新签名
2、在写入渠道信息之后,增加一个签名脚本,写入渠道后再签名,自然就没有问题了
4、需要改进的地方
不支持v2签名,后续会把支持v2签名的脚本上传上来。原理都来自美团的walle。
5、源码
1、写入渠道的脚本 fastChannel.gradle
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.file.Paths
/**
* 多渠道写入脚本
* Created by zhangjianliang on 2018/12/6
*/
//多渠道打包相关配置
// 发布文件夹 (绝对路径)
def packageLocPath = "/var/lib/jenkins/workspace/AKULAKU_ANDROID/outputs"
def windowsPackagePath = "${rootProject.rootDir}/outputs"
// 最终发布包存放的子目录
def childPath = "publish"
// 打包日期
def releaseTime = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
// 发布包前缀
def baseAppName = "Akulaku"
// 渠道文件名
def channelFileName = "channel.txt"
// 渠道名:渠道值
def packageChannelMap = [:]
// 读取渠道值文件闭包 "渠道名:渠道值" 一行一个渠道
def readChannelFromFile = { String path ->
def channelMap = [:]
new File(path).eachLine {
String[] channelStr = it.split(":")
def channelName = channelStr[0].trim()
def value = "";
if (channelStr.length > 1) {
value = it.split(":")[1].trim()
}
channelMap[channelName] = value
}
return channelMap
}
// 准备渠道 key-value
packageChannelMap = readChannelFromFile("${rootDir}/${channelFileName}")
// 判断是否为 Windows 系统
def isWindowsOS = {
return System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0
}
// 判断是否为 Mac 系统
def isMacOS = {
return System.getProperty