本篇博客 主要为本人学习过程总结,有不对的地方麻烦指出,一起学习进步
前言
最近也是搞到了一个 电子书 《Android+Gradle权威指南》,学习一波Gradle 知识,尝试配置签名设置和配置Walle实现多渠道打包。阅读时间:15分钟
签名
视图方式
我们便可以通过点击左上角的Build->Generate Signed APK->Next,如果没有jks 文件,则需要自己创建,然后选择对应的Build Type进行打包。
对于部分不用上架的App来说,这波操作还可以接受,但是如果需要上传到国内的各个平台则需要多次重复这个操作,能把人搞死…,通过这篇文章可以学到 Gradle 签名配置 及 Walle 配置实习 多渠道打包。
Gradle 配置签名
我们先来看一下新建的项目 默认的 app gradle文件默认主要配置如下,
- 准备工作
首先将我们生成好的 jks文件放到project 目录下
- 修改 app build.gradle
defaultConfig {
....
}
signingConfigs {
release {
storeFile file(../ymcandroid.jks)//签名文件路径
storePassword ymc******
keyAlias key0
keyPassword ymc******//签名密码
println("====== signingConfigs.release ======")
}
}
上述代码中的部分变量分别对应于 视图打包中的 我们需要添加的 jks 文件相关信息。
- 坑: signingConfigs代码块一定要写在buildTypes前面,否则会报下面这种错: Could not find property ‘debugConfig’ on SigningConfig container.
- 打包Release apk 包
我们在项目路径下的app/build/outputs可以看到我们打包的apk。
这里也上下我的 buildTypes 配置
buildTypes {
release {
minifyEnabled false
//是否移除无用资源
zipAlignEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
上述已经是简单的 签名了,但是我这个wanAndroid 项目需要上传到Github上,所以我们这里先说一下 忽略文件,在上传git 的时候,我们将忽略部分文件,以下是我项目中的忽略文件配置
# Built application files //
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
/local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
.idea/workspace.xml
# Keystore files
*.jks
*.iws
.idea/
我们可以在其中找到我们将要配置 jks密码信息的 local.properties 文件。
ndk.dir=E\:\\AndroidSDK\\ndk-bundle
sdk.dir=E\:\\AndroidSDK
keystore.path=../ymcandroid.jks
keystore.password=ymc******
keystore.alias=key0
keystore.alias_password=ymc******
我们这里就需要修改 app build.gradle 文件,将明文的地方替换掉
def keystoreFilepath = ''
def keystorePSW = ''
def keystoreAlias = ''
def keystoreAliasPSW = ''
// default keystore file, PLZ config file path in local.properties
def keyfile = file('s.keystore.temp')
Properties properties = new Properties()
// local.properties file in the root director
properties.load(project.rootProject.file('local.properties').newDataInputStream())
keystoreFilepath = properties.getProperty("keystore.path")
if (keystoreFilepath) {
keystorePSW = properties.getProperty("keystore.password")
keystoreAlias = properties.getProperty("keystore.alias")
keystoreAliasPSW = properties.getProperty("keystore.alias_password")
keyfile = file(keystoreFilepath)
}
android {
compileSdkVersion 27
defaultConfig {
applicationId "cn.white.ymc.wanandroidmaster"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
signingConfigs {
release {
storeFile keyfile//签名文件路径
storePassword keystorePSW
keyAlias keystoreAlias
keyPassword keystoreAliasPSW //签名密码
println("====== signingConfigs.release ======")
}
}
buildTypes {
release {
minifyEnabled false
//是否移除无用资源
zipAlignEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//签名文件存在,则签名
if (keyfile.exists()) {
println("WITH -> buildTypes -> release: using jks key")
signingConfig signingConfigs.release
}else {
println("WITH -> buildTypes -> release: using default key")
}
}
}
}
dependencies {
...
}
上述代码 主要修改地方 就是使用 gradle 语法读取 local.properties文件,获取其中信息,如果有就 签名打包。这样我们就可以保证 key文件的安全性了。
讲完 签名,我们就需要来看 Walle 的配置和部分Gradle 相关操作。
Walle 打包
为什么使用 美团多渠道打包
打包更加快速传统的通过productFlavors渠道包的方式,渠道10个以内还可以接受,如果100个渠道包,要死人,而采用美团Walle多渠道打包的方式只需要打一个包的时间。
配置更加灵活可以在APK渠道包中通过配置config文件,针对于不同渠道包配置各个渠道定制化额外信息。
原理
整个APK(ZIP文件格式)会被分为以下四个区块:
Contents of ZIP entries(from offset 0 until the start of APK Signing Block)
APK Signing Block
ZIP Central Directory
ZIP End of Central Directory
这个是V2签名包的APK包格式,新的应用签名方案有着良好的向后兼容性,能完全兼容低于Android 7.0(Nougat)的版本。区块1、3、4都是受保护区块,不允许修改保护区块。美团打包的方式,是在2区块内写入ID-value的扩展信息(渠道信息),并保存到APK中。这样,每打一个渠道包只需复制一个APK,然后在APK中添加一个ID-value即可。
walle 配置
项目的根目录 build.gradle 文件中添加Walle Gradle插件的依赖
classpath 'com.meituan.android.walle:plugin:1.1.6'
App的 build.gradle 文件中apply这个插件,并添加上用于读取渠道号的AAR
apply plugin: 'walle'
dependencies {
compile 'com.meituan.android.walle:library:1.1.6'
}
我们单独新建一个 gradle 用来保存配置插件 multlple-channel.gradle,内容如下
apply plugin: 'walle'
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels")
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
部分配置解析
apkOutputFolder:指定渠道包的输出路径, 默认值为new File("${project.buildDir}/outputs/apk")
apkFileNameFormat:定制渠道包的APK的文件名称, 默认值为 {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 名
记得在添加完成后 一定要在app build.gradle 文件中引入
apply from: 'multlple-channel.gradle'
接下来配置 channelFile
meituan # 美团
samsungapps #三星
hiapk
anzhi
xiaomi # 小米
91com
gfan
appchina
nduoa
3gcn
mumayi
10086com
wostore
189store
lenovomm
hicloud
meizu
wandou
# Google Play
# googleplay
# 百度
baidu
#
# 360
360cn
#
# 应用宝
myapp
上述 市场平台,读者可以自行删减留下需要的,接下来我们使用 Android Studio 进行打包
打包会经历一段时间,等成功后,我们打开 配置输出地址
就可以看到我们需要的 各个渠道的安装包了。