随着Jetpack Compose正式版的发布,打算尝鲜一下,Jetpack Compose强制绑定了AGP 7.0 和 kotlin 1.5.31,kotlin 1.5.31好办,但AGP 7.0又强制搭配Gradle 7.0 和 JDK 11,正好春节期间没什么大事,可以尝试一下升级。
当前项目的组合是Gradle 6.9 + AGP 4.2.2,为了避免同时升级AGP和Gradle引入过多的变量,可以一步一步来,先升级Gradle 7.0,最后是升级AGP 7.0 + JDK 11。
一、Gradle 6.9 -> 7.3.2
1. Cannot run Project.afterEvaluate(Closure) when the project is already evaluated
第一个报错:
Cannot run Project.afterEvaluate(Closure) when the project is already evaluated.
定位到下面这一段:
def installCustomLintTask = tasks.findByPath(":lint:install")
subprojects {
afterEvaluate { Project project ->
...
}
}
stackoverflow给到的答案是把afterEvaluate里面的内容移到plugin中去,尝试了一下确实可以,但疑惑的是,项目中也挺多afterEvaluate,怎么只有这一处报错,原来问题其实出在def installCustomLintTask = tasks.findByPath(":lint:install"),这一行出现了在afterEvaluate外面,而findByPath会引发evaluate,所以才会出现is already evaluated的情况
2. property ‘xxx’ is missing an input or output annotation
报错例子如下:
> In plugin 'com.google.protobuf' type 'com.google.protobuf.gradle.ProtobufExtract' property 'destDir' is missing an input or output annotation.
Reason: A property without annotation isn't considered during up-to-date checking.
Possible solutions:
1. Add an input or output annotation.
2. Mark it as @Internal.
Please refer to https://docs.gradle.org/7.2/userguide/validation_problems.html#missing_annotation for more details about this problem.
参考报错中给的解法,第一加上@input或者@output的注解来提高构建缓存命中率;或者直接加上@Internal。两种方法都行,就算具体的属性是不是需要纳入缓存了。
一、AGP 4.2.2 -> 7.0.2
这一步比想象中要顺利,基本没有报错,只有一个JDK的要求:
* What went wrong:
A problem occurred evaluating script.
> Failed to apply plugin 'com.android.internal.application'.
> Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
You can try some of the following options:
- changing the IDE settings.
- changing the JAVA_HOME environment variable.
- changing `org.gradle.java.home` in `gradle.properties`.
解决方法就是设置JAVA_HOME到JDK 11即可。
问题少的原因主要是在升级AGP 4.2.2过程中把提示预计在7.0要废弃的借口都给提前修改了。但AGP 7.0改动其实还是比较大的,可以参考https://developer.android.google.cn/studio/releases/gradle-plugin#7-0-0,具体来说:
新的variant api成为了稳定版本
这个改动涉及老的写法被废除:
android.applicationVariants.all {
}
改成:
androidComponents {
onVariants(selector().withName("all"), { variant ->
})
}
如果只针对debug varaint,就把上面的all改成debug即可。
其他的还有简化task之间关系的Artifacts,再也不用dependsOn、finalizedBy了,具体可以参考官方demo
由于老版本variant api相关接口要在AGP 8中移除,所以现在还不着急适配新variant api。(但其实也不远了,官方蓝图中AGP 8将会在2022年上半年到来)