文章内容:配置不同打包环境下(包括run运行的debug打包模式)指定签名,配置本地jks_config文件,自动编译签名包
还记得当初刚撸android时,在一家小公司用的eclipse开发,遇到一个发布bug,自己在运行debug打包模式测试都没有遇到过,但是通过jks签名包出来就升级安装出问题了,着实蛋疼,可想,配置一个正确的开发和测试环境的重要性,当我们打测试包时,总不能一直给人家debug签名版,不然多个电脑一起编译便会出现签名冲突问题,所以在debug模式下配置自定义签名也非常重要。同时,我们既然叫自动签名,那么总不能自己手动输入密码吧,那么配置签名文件密文如何放置才安全呢,且看文章吧
多渠道打包在前2年面试可是必问知识点,其实实现起来非常简单,都是基本操作,实在也想不通有什么好问的,不过涉及到深入的技术,包括埋点统计等等,这些还是非常考验架构搭建的,在大型项目中也是重中之重。通过gradle简单的配置多渠道分包打包,结合上面修改打包报名一起修改如下:
AndroidManifest替代符
gradle配置
gradle配置自动签名,通过明文写入gradle不太安全,网上看到很多是通过命令控制台输入,不过还是不太喜欢,有点懒,我觉得通过本地保存比较舒服,动态读取。
在gradle.properties中配置
# 配置release签名信息保存地址
AutoGradleDemo.propertiesPath= D:\\appkey\\AutoGradleDemo.properties
# 配置debug签名配置,直接放在本地就行
AutoGradleDemo.debugStorePath=./AutoGradleDemoDebug.jks
AutoGradleDemo.debugStorePassword=123456
AutoGradleDemo.debugKeyAlias=debugKey
AutoGradleDemo.debugKeyPassword=123456
在moudle build.gradle配置
android {
//...
//加载gradle.properties中存储的release配置文件路径
if (project.hasProperty("AutoGradleDemo.propertiesPath")
&& new File(project.property("AutoGradleDemo.propertiesPath")).exists()) {
Properties props = new Properties()
//读取配置文件
props.load(new FileInputStream(file(project.property("AutoGradleDemo.propertiesPath"))))
println("AutoGradleDemo: propertiesPath :" + project.property("AutoGradleDemo.propertiesPath"))
//导入release配置信息
signingConfigs {
release {
def storeFile_str = props['AutoGradleDemo.storeFile']
def keyAlias_str = props['AutoGradleDemo.keyAlias']
def keyPassword_str = props['AutoGradleDemo.keyPassword']
def storePassword_str = props['AutoGradleDemo.storePassword']
if (keyAlias_str != null && keyPassword_str != null && storePassword_str != null && storeFile_str != null) {
println("storeFile: " + storeFile_str)
println("keyAlias: " + keyAlias_str)
println("keyPassword:" + keyPassword_str)
println("storePassword:" + storePassword_str)
storeFile file(storeFile_str + ".jks")
storePassword storePassword_str
keyAlias keyAlias_str
keyPassword keyPassword_str
println(getPath() + "-" + getName() + " pull release-configs successed!")
} else {
println("error: " + getPath() + "-" + getName() + " no jks-configs! ")
}
}
//debug签名配置在mould下全局gradle.properties
debug {
storeFile file(project['AutoGradleDemo.debugStorePath'])
storePassword project['AutoGradleDemo.debugStorePassword']
keyAlias project['AutoGradleDemo.debugKeyAlias']
keyPassword project['AutoGradleDemo.debugKeyPassword']
}
}
} else {
println("error: " + getPath() + "-" + getName() + " AutoGradleDemo.propertiesPath is not exists! ")
}
//声明打包配置
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
}
}
}
release签名文件和信息存储目录
其中AutoGradleDemo.properties配置文件内容
AutoGradleDemo.storeFile=D:\\appkey\\AutoGradleDemo
AutoGradleDemo.keyAlias=auto_gradle
AutoGradleDemo.keyPassword=654321
AutoGradleDemo.storePassword=123456
目录
Gradle编译结果
通过检查每次release打包指令,去自增版本号,不过当然有更好的方法,通过获取git分支配置versionCode,versionName,这个只是给个参考,想要更详尽和高级的使用方法,参考我的《自动化构建总结篇》文章
/**
* 从 AutoGradleDemo.properties中读取信息, 检查到release打包,版本号自增,并存入到文件
* @param path
* @return
*/
def configAutoCompileInfo(def path) {
def configsInfoFile = file(path)
if (!configsInfoFile.canRead()) {
throw new Exception("Could not find version.properties!")
}
Properties props = new Properties()
//读取配置文件
props.load(new FileInputStream(configsInfoFile))
println("AutoGradleDemo: propertiesPath :" + path)
def versionCode = props['AutoGradleDemo.versionCode'].toInteger()
def versioName = props['AutoGradleDemo.versioName'].toString()
/*检查到跑release task时版本号叠加*/
def runTasks = gradle.startParameter.taskNames
if ('assembleRelease' in runTasks) {
props['AutoGradleDemo.versionCode'] = (++versionCode).toString()
props.store(configsInfoFile.newWriter(), null)
println("AutoGradleDemo: release versionCode increase current=" + props['AutoGradleDemo.versionCode'])
}
return props
}
//加载gradle.properties中存储的release配置文件路径
if (project.hasProperty("AutoGradleDemo.propertiesPath")
&& new File(project.property("AutoGradleDemo.propertiesPath")).exists()) {
Properties props = configAutoCompileInfo(project.property("AutoGradleDemo.propertiesPath"))
defaultConfig {
applicationId "com.auto.gradle"
minSdkVersion 18
targetSdkVersion 28
versionCode props['AutoGradleDemo.versionCode'].toInteger()
versionName props['AutoGradleDemo.versionName']
if (versionCode != 0 && props['AutoGradleDemo.versionName'] != null) {
println("versionCode: " + versionCode);
println("versionName: " + versionName);
} else {
throw new Exception("error: versionCode pull failed!")
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
} else {
throw new Exception("error: " + getPath() + "-" + getName() + " AutoGradleDemo.propertiesPath is not exists! ")
}
通过判断包名以及多渠道名称,动态生成包名
gradle.properties
#定义输出路径
AutoGradleDemo.outReleaseFile=./app/relaseApk
AutoGradleDemo.outDebugFile=./app/debugApk
#定义包名
AppName.release=AutoGradleDemoRelease
AppName.debug=AutoGradleDemoDebug
APP:build.gradle
applicationVariants.all { variant ->
variant.outputs.all {
def fileName
//打包类型
def buildType = variant.buildType.name
//渠道名称
def channelName = variant.productFlavors[0].name
//获取时间戳
def currentTime = new Date().format("YYYY_MM_dd", TimeZone.getTimeZone("GMT+08:00"))
//制定输出路径
if (buildType == "release") {
variant.getPackageApplication().outputDirectory = new File(project['AutoGradleDemo.outReleaseFile'] + "/${currentTime}")
println "compile name:-----------------${variant.getPackageApplication().outputDirectory}"
fileName = project['AppName.release'] + "_${channelName}_v${defaultConfig.versionName}_${currentTime}_${buildType}.apk"
println "compile name:-----------------${fileName}"
outputFileName = fileName;
}
}
}
结果
在网上很多gradle学习文章都是讲输出在gradle console,其实就是在build中查看就行
这个问题主要会发生的win系统,在配置参数文件时,空格或者其他特殊符号都是会默认读进去的,因此这些都是要注意项。使用Linux系统的同学,只要通过文档打印换行后缀就能发现,要简单很多。
https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/