Gradle 作为一款灵活多变的构建插件,与 Android Studio 的结合,能够解决过去使用 Eclipse 开发 App 时所遇到的诸多问题。同时,基于 Groove 这样一款 DSL 语言的脚本特性,记住各种语法显然又是一件比较困难的事情。
事实上,Gradle 插件的常用使用场景并不是很多,也不需要死记硬背,或者完全学会 Groove 的所有使用方式。这里将 Android 开发中较为常用的 Gradle 使用场景总结出来,用于将来需要的时候有个参考。
多渠道打包
举一个最常见的多渠道使用场景,友盟统计,看看最基本的 Gradle 多渠道打包方式的用法。
修改 Manifest 文件中友盟统计的渠道名为引用变量(变量名自取):
<meta-data
android:name="${UMENG_CHANNEL_VALUE}"
android:value="Channel_ID" />
然后在 build.gradle 文件 productFlavors 配置项中添加渠道名,并统一设置到上面提到的变量名:
android {
productFlavors {
xiaomi {}
yingyongbao {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
执行打包 Task 的命令语句即可:
./gradle assembleRelease
或者有针对性的只打特定渠道包,如:
./gradle assembleXiaomiRelease
备注:在 Gradle projects 窗口中能够查看所有可执行的 Tasks 列表。这种原生态打包方式适合渠道名比较少的使用场景。当渠道多达数十个甚至上百个时,打包时间就会比较长,推荐其他打包方案,如:
自定义输出 APK 文件名
可以修改打包输出的 apk 文件名,添加时间戳、编译类型、版本信息等关键字,是 apk 文件更具识别性,如:
apply plugin: 'com.android.application'
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, rootProject.getName()
+ "-" + buildType.name
+ "-" + releaseTime()
+ "-v" + defaultConfig.versionName
+ "-" + defaultConfig.versionCode
+ ".apk");
}
}
}
这里将项目名称添加到 apk 文件名中,也可以使用 applicationId 等,结果如下:
YFSample-release-2017-09-12-v1.0-1.apk
Debug 和 Release 相同签名
android {
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "DEBUG_MODE", "true"
signingConfig signingConfigs.config
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "DEBUG_MODE", "false"
signingConfig signingConfigs.config
}
}
}
这一步操作可以通过图形化界面操作,更方便一些。右键项目,点击 Open Module Settings,打开 Project Structure 窗口,在 Build Types 选项卡中设置。
隐藏签名信息
签名信息作为项目里最为私密的一部分内容,如果直接暴露在 build.gradle 文件中,显然不够安全。尤其是需要上传到 GitHub 等托管平台时。
比较妥当的做法是,在项目根目录下新建一个专门用来存储签名信息的文件,并且将其添加到 ignore 文件配置当中。具体操作过程如下:
第一步,新建一个 keystore.properties 文件:
ReleaseKeyPassword=sampleKeyPwd
ReleaseKeyAlias=sampleAlias
ReleaseStorePassword=sampleStorePwd
ReleaseStoreFile=../sample.jks
第二步,在 build.gradle 文件的最外层引入签名信息:
allprojects {
afterEvaluate { project ->
def propsFile = rootProject.file('keystore.properties')
def configName = 'config'
if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
android.signingConfigs[configName].storeFile = file(props['ReleaseStoreFile'])
android.signingConfigs[configName].storePassword = props['ReleaseStorePassword']
android.signingConfigs[configName].keyAlias = props['ReleaseKeyAlias']
android.signingConfigs[configName].keyPassword = props['ReleaseKeyPassword']
}
}
}
如此即可。其中第二步还有一种缩减版的写法,也可以直接使用:
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
config {
storeFile file(keystoreProperties['ReleaseStoreFile'])
storePassword keystoreProperties['ReleaseStorePassword']
keyAlias keystoreProperties['ReleaseKeyAlias']
keyPassword keystoreProperties['ReleaseKeyPassword']
}
}
}
当然,隐藏签名信息的方式还有很多。比如配置在本地环境变量中,或者 build.gradle 文件中,或者编译时从命令行中动态读取输入内容等,设置不同,读取方式有所不同。
日志开关
在 app/build.gradle 文件中分别定义 debug 和 release 不同编译模式的控制变量,变量名可自由更改:
buildTypes {
debug {
buildConfigField "boolean", "DEBUG_MODE", "true"
}
release {
buildConfigField "boolean", "DEBUG_MODE", "false"
}
}
重新编译后,自动生成的 BuildConfig 类中包含上面定义的 DEBUG_MODE 属性,即可使用。
Log 日志开关更多解决方案,可参考:Android 中能够作为 Log 开关的一些操作以及安全性浅谈。
环境分离
开发中测试服务器和生产服务器的同时使用也是很常见的场景之一,如何在一台设备中同时安装配置测试环境的 debug 包和生产环境的 release 包,也是需要面对的问题。不妨参考我的这篇文章:
Android 利用 Gradle 实现 app 的环境分离
参考链接
学习有关 Android、Gradle 和 Groove 更多详细信息,除了访问 Gradle 官方网站,推荐你阅读这些文章:
END
关于我:亦枫,博客地址:http://yifeng.studio/,新浪微博:IT亦枫
微信扫描二维码,欢迎关注我的个人公众号:安卓笔记侠
不仅分享我的原创技术文章,还有程序员的职场遐想
网友评论