简评:用 Gradle Task 简化工作流程,了解一下。
在 Android 开发中 Gradle 除了默认用来构建 APK 之外,我们还可以用其帮忙处理一些可以自动化的工作。
比如:自动化打包签名 APK 的工作。
首先,在项目的 /app 目录下创建一个 signing.gradle 文件,但请确保这个文件不要被提交到仓库。
ext.signing = [
storeFilePath : '/path/to/your/keystore-file',
storePassword : 'your-store-password',
keyAlias : 'your-key-alias',
keyPassword : 'your-key-password',
]
再在 build.gradle 文件中添加以下代码:
def signingFilePath = 'signing.gradle'
def performSigning = file(signingFilePath).exists()
if (performSigning) {
apply from: signingFilePath
}
...
android {
...
if (performSigning) {
signingConfigs {
release {
storeFile file(project.signing.storeFilePath)
storePassword project.signing.storePassword
keyAlias project.signing.keyAlias
keyPassword project.signing.keyPassword
v1SigningEnabled true
v2SigningEnabled true
}
}
}
...
buildTypes {
release {
...
if (performSigning) {
signingConfig signingConfigs.release
}
}
}
}
之后,只要运行 *./gradlew assembleRelease *命令,就可以得到一个已签名的 release apk 文件了。
在 Gradle 中最重要的两个概念就是 project 和 task。每个构建流程可以有一个或多个项目(project),而项目再由任务(task)组成。如果你看过自己 Android 项目的 Gradle projects 面板,肯定会注意到其中列出的很多任务。
当然,我们完全可以自定义任务来做各种各样的事情。比如:生成 release apk 文件,将 apk 文件复制到指定目录并重命名,最后再发一条消息到 Slack。
具体流程:
- 检查 apk 文件将要移动到的文件夹是否存在。
- 打包 release apk 文件。
- 检查是否成功生成。
- 复制,粘贴到目标文件夹。
- 重命名 apk 文件。
- 给 Slack 发一条消息。
Task 1:判断文件夹路径是否存在。
def targetPath = file("/Your/Target/Path")
task verifyTargetPath {
doLast {
if (!targetPath.exists()) {
throw new GradleException("Target path not valid!")
}
}
}
Task 2:打包 release apk
这一步我们需要先运行上面定义的 *verifyTargetPath *任务, 再运行 assembleRelease,最后复制 apk 文件到指定目录。所以整个 task 看起来就像这样:
task buildReleaseApk(dependsOn:
['verifyTargetPath', 'assembleRelease']) {
doLast {
// 基于 versionCode 创建 apk 名称。
// 确保不存在相同名字的文件。
// 判断是否已经完成 build,然后把文件复制到目标文件夹。
}
}
其中 *dependsOn *指定了 task 的执行顺序,首先运行 verifyTargetPath,之后是 assembleRelease,最后是 buildReleaseApk。
现在来完成代码:
task buildReleaseApk(dependsOn:
['verifyTargetPath', 'assembleRelease']) {
doLast {
ext.versionCode = project.android.defaultConfig.versionCode
ext.apkName = "android-release-build${ext.versionCode}.apk"
if (targetPath.list().contains(ext.apkName)) {
throw new GradleException("Build with versionCode ${ext.versionCode} already exists!")
}
ext.apk = file("build/outputs/apk/release/app-release.apk")
if (ext.apk.exists()) {
copy {
from ext.apk.absolutePath
into targetPath
rename { ext.apkName }
}
}
}
}
Task 3:完成后给 Slack 发一个通知
我们还可以通过 curl 来给你的 Slack channel 发消息(当然如果对 Slack 不熟的话,就无视吧)。
task buildAndSendNotification(dependsOn: 'buildReleaseApk') {
doLast {
def text = "Build `${buildReleaseApk.apkName}` moved to `${targetPath}`."
def webHook = 'your-webhook-url'
def channel = 'your-channel'
def response = ['curl',
'-X',
'POST',
'--data-urlencode',
"payload={\"channel\": \"${channel}\", \"username\": \"Bot\", \"text\": \"${text}\", \"icon_emoji\": \":ghost:\"}", '${webHook}'].execute().text
println response
}
}
这样你可以实现把 apk 移动到某个云服务的目录下,然后通知 Slack 上的其他人 apk 正在上传。
像这样自己定义一些 Gradle task 可以让我们的工作变得更轻松,建议大家都可以了解尝试下。
英文原文:A bit of automation with Gradle Tasks
推荐阅读:不用 GPS 的精准导航