随着Jetpack Compose正式版的发布,打算尝鲜一下,Jetpack Compose强制绑定了AGP 7.0kotlin 1.5.31kotlin 1.5.31好办,但AGP 7.0又强制搭配Gradle 7.0JDK 11,正好春节期间没什么大事,可以尝试一下升级。

当前项目的组合是Gradle 6.9 + AGP 4.2.2,为了避免同时升级AGPGradle引入过多的变量,可以一步一步来,先升级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_HOMEJDK 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,再也不用dependsOnfinalizedBy了,具体可以参考官方demo

由于老版本variant api相关接口要在AGP 8中移除,所以现在还不着急适配新variant api。(但其实也不远了,官方蓝图中AGP 8将会在2022年上半年到来)