使用美团walle进行多渠道打包可以节省大量的时间, 但是使用中发现一个问题:
之前是使用walle打多渠道包, 然后将apk上传360进行加固; 后来发现加固之后的APP没有了渠道信息, 并且发现360加固完成后的自动重签名只有V1签名
因此需要我们自己手动重签名, 需要调整实现流程: 加固——重签名——多渠道打包
我们希望实现gradle脚本实现自动化加固、签名和多渠道打包
目前可以使用瓦力多渠道打包的Python脚本实现自动化打包, 但是使用的python2.7
版本
另一种思路是使用gradle脚本实现:
在此感谢原创作者:天子卿
附作者文章链接:https://juejin.im/post/5c825ac6f265da2db9129bd0
通过作者文章完成此demo, 如有侵权,请联系删除
首先是集成Walle
这里只简单写下Gradle插件使用方式, 如有其他需求请查看主页Meituan-Dianping/walle
配置build.gradle
在位于项目的根目录
build.gradle
文件中添加Walle Gradle插件的依赖, 如下:
1
2
3
4
5 buildscript {
dependencies {
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
}并在当前App的
build.gradle
文件中apply这个插件,并添加上用于读取渠道号的AAR
1
2
3
4
5 apply plugin: 'walle'
dependencies {
compile 'com.meituan.android.walle:library:1.1.6'
}配置插件
1
2
3
4
5
6
7
8 walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}如何获取渠道信息
在需要渠道等信息时可以通过下面代码进行获取
1 String channel = WalleChannelReader.getChannel(this.getApplicationContext());
实现原理
1. 加固
加固过程: 浏览了360加固官网,整个加固过程其实很简单,主要有以下的三个步骤:
输入360加固平台的帐号、密码
将签名文件上传到加固平台
上传需要加固的apk文件进行加固
关键加固命令行代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
* 360加固
* @param apk 加固的原始apk File
* @param outputPath 输出目录
*/
def reinforceApk(File apk,outputPath) {
println "--- 360 reinforceApk start! ---"
println "reinforce apk:" + apk
if(apk == null || !apk.exists()) {
throw new FileNotFoundException('apk is not exists and cannot reinforce')
println "---360 reinforceApk throw exception and forced stop!---"
}
exec {
commandLine "{命令执行符号}", "-c", "java -jar ${REINFORCE_JAR} -login ${REINFORCE_NAME} ${REINFORCE_PASSWORD}"
commandLine "{命令执行符号}", "-c", "java -jar ${REINFORCE_JAR} -showsign"
commandLine "{命令执行符号}", "-c", "java -jar ${REINFORCE_JAR} -jiagu ${apk} ${outputPath}"
}
println "--- 360 reinforce end! ---"
}说明: 系统环境不同,
{命令执行符号}
也会不同(Linux系统:sh ;Mac系统:bash ;windows系统:powershell);
2. 重签名
加固完成后,对加固apk进行重签名;
使用AndroidSDK中的build-tools目录下, 使用压缩对齐工具和签名工具完成重签名, 步骤如下:
对齐,对Apk文件进行存档对齐优化,确保所有的未压缩数据都从文件的开始位置以指定的对齐方式排列
签名,选择Signature V2
1
2commandLine "{命令执行符号}","-c", "{zipalign工具的文件路径} -v -p 4 {已加固的apk文件路径} {对齐后输出的apk文件路径}"
commandLine "{命令执行符号}", "-c", "{apksigner工具的文件路径} sign --ks {签名文件的位置} --ks-key-alias {alias别名} --ks-pass pass:{签名文件存储的密码} --key-pass pass:{alias密码} --out {签名后输出的apk文件} {对齐后输出的apk文件路径}"
3. 多渠道打包
签名完成后, 使用walle进行多渠道打包
平时使用walle多渠道打包,只需要在app/build.gradle下配置插件,指定渠道包的输出路径和渠道配置文件即 可,最后在Android studio的Terminal中输入./gradlew assembleReleaseChannels,任务执行完成后在指定的 输出路径下生成多个对应的渠道包。具体的流程和细节可参考官方介绍。
这种多渠道打包方式是全自动化构建,很难去干涉到构建流程,不符合我们的需求
在app/build.gradle配置插件时,在官方介绍中并没有找到指定源APK输入路径的方式,估计打包插件默认使用的是app/build/outputs/apk/release下的apk文件,这样就没办法对不同文件路径下的已加固apk包进行多渠道打包。
打包任务设置在assembleRelease之后执行,这个执行依赖封装在插件内部,外部很难修改打包任务依赖于加固任务,在加固任务之后执行。
除了上面的多渠道打包方式之后,walle还提供了另外一种多渠道打包方式,用命令行执行walle提供的walle-cli-all.jar执行打包操作,只需要一条打包命令即可完成打包。
1 | commandLine "sh", "-c", "java -jar {walle-cli-all.jar文件路径} batch -f {渠道文件路径} {要加渠道的apk文件路径} {渠道包的输出路径}" |
walle-cli-all.jar文件下载地址:官方:walle-cli-all.jar, 其他开发提供的编译版本
这里为什么会有两个版本呢! 因为发现了一个比较坑的地方官方的版本打完包会发现在系统9.0(P)下无法正常安装, 相关问题可以查看Issue, 当然你也可以自己拉取源码编译
整体流程
首先,将加固和打包操作封装成自动化操作,利用gradle脚本构建加固任务。
为了代码解耦,我们不在app/build.gradle里面实现加固任务,而是重新建一个gradle文件來实现具体的加固和多渠道打包过程,在app/build.gradle只需要通过apply from: '×××.gradle'
引用这个gradle文件即可,
当需要修改加固的一些代码逻辑时,只需要在这个gradle文件里面修改。
引入工具包。根据自己的系统环境,在加固助手网页选择对应的加固助手工具,下载后将里面的jiagu文件夹拷贝到自己项目的根目录下;
在walle-cli-jar下载链接下载jar包到自己项目中。
确定加固任务的时机。加固任务时机应该在release包生成之后,那么加固任务应该依赖于assembleRelease这个任务,并且设置在这个任务之后执行。
接下来就是我们的基本流程了
1. 找到release包, 一般在`app/build/outputs/apk/release/`路径下
2. 执行加固命令,将release包路径设置到命令中,并指定加固apk文件的输出路径
3. 找到已加固的apk文件,对已加固apk文件进行对齐、重签名。(360已加固的apk文件会在原有的release文件名后面加上"_jiagu")
4. 找到重新签名的apk文件,执行多渠道打包命令。(重签名后的文件名是在原有文件名后面加上"_sign")
1 | task assembleReinforceRelease() { |
代码优化:
- 流程中涉及360加固平台帐号密码等敏感信息,可以将这部分信息放到签名信息所在的文件(eg:keystore.properties)中统一管理,然后将这些信息加载到gradle文件中;
- 各种输入输出的文件路径定义为常量,便于修改和管理;
加固方法:
1 | /** |
压缩对齐方法:
1 | /** |
签名方法:
1 | /** |
添加渠道信息:
1 | /** |
重命名apk:
1 | /** |
涉及到的各种常量,各种密钥名、路径都要根据自己的实际情况修改:
1 | /*加载keystore.properties信息到该gradle文件中*/ |
再次感谢原创作者:天子卿
附作者文章链接:https://juejin.im/post/5c825ac6f265da2db9129bd0
在作者的启发下完成此demo, 如果对你有帮助请不要吝啬star