Walle打包
相关链接
GitHub:https://github.com/Meituan-Dianping/walle
个人代码:https://github.com/linw992/Walle-VasDolly/tree/walle
介绍
Walle(瓦力):Android Signature V2 Scheme签名下的新一代渠道包打包神器
瓦力通过在Apk中的APK Signature Block区块添加自定义的渠道信息来生成渠道包,从而提高了渠道包生成效率,可以作为单机工具来使用,也可以部署在HTTP服务器上来实时处理渠道包Apk的升级网络请求。
两种使用方式:
Gradle插件方式,方便快速集成
命令行方式,最大化满足各种自定义需求
安装
根目录 build.gradle
buildscript {
dependencies {
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
}
APP目录 build.gradle
apply plugin: 'walle'
dependencies {
compile 'com.meituan.android.walle:library:1.1.6'
}
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels")
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk'
// 渠道配置文件
// channelFile = new File("D:/External/WalleApplication/channel")
// print("${project.getProjectDir()}") //D:\External\WalleApplication\app
// channelFile = new File("${project.getProjectDir()}/channel")
// 渠道&额外信息配置文件,与channelFile互斥 都存在时configFile优先执行
// configFile = new File("D:/External/WalleApplication/config.json")
// print("${project.getProjectDir()}") //D:\External\WalleApplication\app
configFile = new File("${project.getProjectDir()}/config.json")
}
apkFileNameFormat:定制渠道包的APK的文件名称, 默认值为’${appName}-${buildType}-${channel}.apk’
可使用以下变量:
projectName - 项目名字
appName - App模块名字
packageName - applicationId (App包名packageName)
buildType - buildType (release/debug等)
channel - channel名称 (对应渠道打包中的渠道名字)
versionName - versionName (显示用的版本号)
versionCode - versionCode (内部版本号)
buildTime - buildTime (编译构建日期时间)
fileSHA1 - fileSHA1 (最终APK文件的SHA1哈希值)
flavorName - 编译构建 productFlavors 名
打包
1)执行walle-cli命令
链接:https://github.com/Meituan-Dianping/walle/blob/master/walle-cli/README.md
查看渠道信息
java -jar walle-cli-all.jar show app\build\outputs\channels\app-com.lin.walle-360cn-release-v1.0-1-20180423-105856.apk
写入渠道 生成app-release_meituan.apk文件
java -jar walle-cli-all.jar put -c meituan app\build\outputs\apk\release\app-release.apk
写入渠道和额外信息
java -jar walle-cli-all.jar put -c meituan -e buildtime=20161212,hash=xxxxxxx app\build\outputs\apk\release\app-release.apk
指定输出文件
java -jar walle-cli-all.jar put -c meituan app\build\outputs\apk\release\app-release.apk app\build\outputs\apk\release\app-release111.apk
2)Gradle配置和命令
channelFile只支持渠道写入,如果想插入除渠道以外的其他信息,请在walle配置中使用configFile
1.配置
channelFile方式:
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件 channel放在APP下
channelFile = new File("${project.getProjectDir()}/channel")
print("${project.getProjectDir()}") //D:\External\WalleApplication\app
//channelFile = new File("D:/External/WalleApplication/channel")
}
configFile方式:都存在时configFile优先执行
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
configFile = new File("${project.getProjectDir()}/config.json")
}
2.打包
全部打包
gradlew clean assembleReleaseChannels
使用临时configFile config.json生成全部渠道包:
gradlew clean assembleReleaseChannels -PconfigFile=D:\External\WalleApplication\config.json
gradlew clean assembleReleaseChannels -PchannelFile=D:\External\WalleApplication\config.json
生成指定渠道 config.json和channel中的都可以
gradlew clean assembleReleaseChannels -PchannelList=meituan
支持 productFlavors
示例channel_product1
gradlew clean assemblechannel_product1ReleaseChannels
获取渠道信息
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
ChannelInfo channelInfo= WalleChannelReader.getChannelInfo(this.getApplicationContext());
if (channelInfo != null) {
String channel = channelInfo.getChannel();
Map<String, String> extraInfo = channelInfo.getExtraInfo();
}
// 或者也可以直接根据key获取
String value = WalleChannelReader.get(context, "buildtime");
加固后重打包
使用360加固后,会出现渠道信息被擦除的情况。这个时候需要我们重新对加固后的安装包进行重新签名。
ProtectedApkResignerForWalle
用法:
- 按照config.py文件中的注释改成自己项目配置
- 将已经加固好的包【未签名的包,请不要使用加固客户端签名工具】放到脚本工具根目录下,即app-release.encrypted.apk
- 各种渠道的定义是在channel这个文件中,请根据项目情况修改
- 运行命令 python ApkResigner.py,即可自动生成所有渠道包。
支持平台:(需要python环境)
Windows (Test)
Mac OS (Test)
Linux
注意:python2.x版本正常,python3.x待测试
Python官方下载地址
打包失败
- 保证你Android程序的compileSdKVersion 和 buildToosVersion 版本相同
- 建议将jdk升级到1.8
- 保证自己本地打包签名可以正常运行
- 保证配置的相关路径正确,编码格式为UTF-8,不要带异常字符。
- Android SDK buidtools请使用25.0+版本,越新越好。
- 检查安装的Python版本
检查Python版本是否是Python2.X(由于我的电脑之前安装的是Python 3.6.3,所以没有使用官方推荐的Python 2的环境。) - 检查config.py配置
检查config.py中涉及到的文件地址,测试文件地址是否存在。
如果上述步骤正确,还是出现打包失败的问题。那么就是ApkResigner.py脚本在我们当前的环境下 (Windows+Python3) 不能够正常的运行。
执行python ApkResigner.py命令,报错:
Zip alignment utility
Copyright (C) 2009 The Android Open Source Project
Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip
zipalign -c [-p] [-v] <align> infile.zip
<align>: alignment in bytes, e.g. '4' provides 32-bit alignment
-c: check alignment only (does not modify file)
-f: overwrite existing outfile.zip
-p: memory page alignment for stored shared object files
-v: verbose output
-z: recompress using Zopfli
Unexpected parameter(s) after input APK (C:\Studio)
Error: Unable to access jarfile C:\Studio
出现Zip alignment utility,应该是执行对齐命令zipalign 时,语法有问题。
为了方便排查出错的原因,我在ApkResigner.py脚本中添加了输出代码。发现是由于路径没有添加双引号,导致执行zipalign、签名、写入命令时出错。在脚本文件中对路径添加双引号后,便解决。修改后的脚本地址