在学习过程中最痛苦的事,并不是认为自己坚持不下去学不会,而是对某块知识点的碎片信息学习了很多,仍然无法窥其门径,处于懵懂状态。
就拿Gradle来说,我之前就是这种状态,不管怎么去查阅文档和视频,一直有些知识点搞不懂,但是自己起手完成过一个需求后,才发现Gradle 也不是那么难学懂嘛,虽然中间也踩了不少的坑。
中间遇到的问题有:
- 如何创建 private、public 两个 build variants(构建变体)?
- 如何配置 public 版本在 private 版本之前构建(因为 private 版本依赖 public 版本生成的 apk)?
- public 版本构建完成后,如何自动复制其生成的 apk 到 private 版本的 assets 目录下?
解决方案:
- 关于构建变体,其实就是一次编译,输出多个版本的 apk,具体内容请参考官方文档中文版《配置构建变体》
- 两个构建变体,说明对应两个 assemble task,那么只要获获取到这两个 task 对象,然后设置其依赖关系即可
- Gradle 文件支持 groovy 编写,groovy 又是基于 java 的,所以即使不熟悉 groovy 的语法,也可以用 java 写出来。不过对于复制这种操作,Gradle 有现成的 API
编写流程
方案很清晰:assemblePublicApp -> deleteOldPublicApp -> signNewPublicApp -> copyNewPublicApp -> assemblePrivateApp
但是代码怎么写呢?我一时间感到无从下手。比如如何获取两个构建变体对应的 assemble task?如何创建一个 copy task?又如何在执行 copy task 之前先执行 delete task(删除 assets 目录下的旧 apk) 以及 sign task(签名 public apk)?
我一顿 google 搜索之后解决了这些问题,不过也踩了一个坑,就是自定义 task 内的代码执行时机不对。比如 deleteOldPublicApk task 中的日志,总是在执行 gradle assemble 命令之后立即输出,而不是在 assemblePublicApp task 之后输出:
File -> Demo/app/build.gradle
android {
...
}
task deleteOldPublicApk(type: Delete) {
println("-----------> delete the old pubic apk begin") // 注意:这么写代码会在配置阶段立即执行
delete 'src/privateApp/assets/Public.apk' // delete 方法继承自 Delete task,所以是一个 Action,在执行阶段才会被执行
println("-----------> delete the old pubic apk end") // 注意:这么写代码会在配置阶段立即执行
}
task signNewPublicApp() {
doFirst {
println 'sign the new public app' // 写在 doFirst 或者 doLast 中,才会在执行阶段被执行,具体见下文
}
}
task copyNewPublicApp() {
doLast {
println 'copy the new public app'
}
}
afterEvaluate {
def assemblePublic = tasks.getByName('assemblePublicAppRelease')
deleteOldPublicApk.dependsOn(assemblePublic)
copyNewPublicApp.dependsOn(deleteOldPublicApk, signNewPublicApp)
def assemblePrivate = tasks.getByName('assemblePrivateApp')
assemblePrivate.dependsOn(copyNewPublicApp)
}
dependencies {
...
}
如上所示的 deleteOldPublicApk
task,只要在 terminal 中 输入 gradlew assemble
必然会首先打印:
-----------> delete the old pubic apk begin
-----------> delete the old pubic apk end
相信很多不熟悉 Gradle 的人都会犯这样的错误,stackoverflow 上有人也发出了同样的疑问 Why is my Gradle task always running?
后来我阅读了 Gradle 的官方文档 《Build Lifecycle》,恍然大悟,应该这么写:
task deleteOldPublicApk(type: Delete) {
doFirst {
println("-----------> delete the old pubic apk begin")
}
delete 'src/privateApp/assets/Public.apk'
doLast {
println("-----------> delete the old pubic apk old")
}
}
于是在我自己弄得以后,整理了一个《Gradle 入门到精通》学习笔记,根据自己学习中所做的一些笔录来整的,主要也是方便后续好复习翻阅,省掉在去网上查找的时间,以免在度踩坑,如果大家有需要的可以直接通过点击此处↓↓↓进行参考学习!!!
有需要的可以复制下方链接,传送直达!!!
https://qr21.cn/CaZQLo?BIZ=ECOMMERCE
网友评论