前言
在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2
,它是一个对全文件进行签名的方案,能提供更快的应用安装时间、对未授权APK文件的更改提供更多保护,在默认情况下,Android Gradle 2.2.0插件会使用APK Signature Scheme v2
和传统签名方案来签署你的应用(可通过v2SigningEnabled false
关闭)。APK Signature Scheme v2
导致之前快速生成渠道包的方式(如:美团Android自动化之旅—生成渠道包)已经行不通了,至于为什么行不通了在这篇文章中(Android 新一代多渠道打包神器)能找到答案,在此便不再赘述。目前针对APK Signature Scheme v2
快速生成渠道包的市面上的解决方案有(两者的实现原理都一样,本文主要介绍前者):
- Walle
- ApkChannelPackage
Gradle插件使用方式
1. 配置build.gradle
在位于项目的根目录 build.gradle
文件中添加Walle Gradle插件的依赖, 如下:
buildscript {
dependencies {
classpath 'com.meituan.android.walle:plugin:1.1.2'
}
}
并在当前App的 build.gradle
文件中apply这个插件,并添加上用于读取渠道号的AAR
apply plugin: 'walle'
dependencies {
compile 'com.meituan.android.walle:library:1.1.2'
}
2. 配置插件
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")
}
配置项具体解释:
- apkOutputFolder:指定渠道包的输出路径, 默认值为
new File("${project.buildDir}/outputs/apk")
- 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 名
- channelFile:包含渠道配置信息的文件路径,文件支持使用#号添加注释,具体内容格式示例:
Baidu
Tencent
Huawei
Pp
Vivo
3. 获取渠道信息
在需要渠道等信息时可以通过下面代码进行获取
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
4. 生成渠道包
生成渠道包的方式是和assemble${variantName}Channels
指令结合,渠道包的生成目录默认存放在build/outputs/apk/
,也可以通过walle
闭包中的apkOutputFolder
参数来指定输出目录
用法示例:
- 生成渠道包
./gradlew clean assembleReleaseChannels
- 支持 productFlavors
./gradlew clean assembleMeituanReleaseChannels
- 临时生成某渠道包
./gradlew clean assembleReleaseChannels -PchannelList=baidu
说明:使用以上命令处的 clean
有的时候会导致R文件报错,可见issues, 解决方案:
- 使用AS 的buid——> clean
- 使用
./gradlew assembleReleaseChannel
360加固渠道信息失效解决方案
1.将应用上传360加固,加固完后下载到本地备用
2.使用Android SDK中的zipalign
对齐优化
- 打开CMD,进入Android SDK -> build-tools -> 25.+目录
例如:cd /Users/pugongying/work/android/android_dev/android/sdk/Build-Tools/25.0.3
- 执行命令
./zipalign -v 4 input.apk output.apk
例如:./zipalign -v 4 /Users/pugongying/work/down_apk/app-debug.apk /Users/pugongying/work/down_apk/app-debug-ziplign.apk
3.使用V2签名工具再次签名加固后的Apk
- 打开CMD,进入Android SDK -> build-tools -> 25.+目录
例如:cd /Users/pugongying/work/android/android_dev/android/sdk/Build-Tools/25.0.3
- 执行命令
./apksigner sign --ks [你的签名文件] [apk路径]
例如: ./apksigner sign --ks /Users/pugongying/work/release_wcg.jks /Users/pugongying/work/down_apk/app-debug-ziplign.apk
4.检查是否使用V2签名
需要下载CheckAndroidV2Signature.jar
下载链接
执行命令:java -jar [jar路径] [apk路径]
例如:java -jar /Users/pugongying/work/CheckAndroidV2Signature.jar /Users/pugongying/work/down_apk/app-debug-ziplign.apk
执行命令返回:
{"ret":0,"msg":"ok","isV2":true,"isV2OK":true} 是V2 签名的App
{"ret":0,"msg":"ok","isV2":false,"isV2OK":false} 不是 V2 签名的App
5.写入渠道信息
需要下载walle-cli-all.jar
下载地址
单个写入:java -jar [jar路径] put -c [渠道名] [apk路径] [生成的apk路径(可选)
例如:java -jar walle-cli-all.jar put -c tentxun /Users/pugongying/work/down_apk/app-debug-ziplign.apk
批量写入:java -jar [jar路径] batch -f [渠道文件] [apk路径] 生成的apk路径(可选)
例如:java -jar walle-cli-all.jar batch -f /Users/pugongying/work/channel.txt /Users/pugongying/work/down_apk/app-debug-ziplign.apk
说明:以上命令未指定生成apk路径,生成的新apk与当前apk同级目录
6.显示渠道信息
执行命令:java -jar [jar路径] show [apk路径]
例如:java -jar walle-cli-all.jar show /Users/pugongying/work/down_apk/app-debug-ziplign.apk
结果:{channel=Xiaomijingpin}
对tinker影响
有的应用集成了tinker,经过测试,对tinker补丁包无影响,tinker可正常使用
参考资料
新一代开源Android渠道包生成工具Walle
360加固后获取不到渠道信息
Android 新一代多渠道打包神器