JDK和Gradle升级那些事

2,029 阅读2分钟

我想作为一个Android开发者,应该对JDK和Gradle有一定的了解。但是,有时,还是会被jdk和gradle的版本所坑到。今天我们就来聊聊这个话题。

我们先来看看JDK和Gradle版本的对应关系。为什么是Gradle去适配JDK?我想不用多说,先有JDK,而后有Gradle,Gradle作为构建脚本,肯定是基于JDK的。

JDK版本支持该JDK的最低Gradle版本
82.0
94.3
104.7
115.0
125.4
136.0
146.3
156.7
167.0
177.3
187.5
197.6
208.1

然后我们就确定了Gradle版本,确定了Gradle版本,我们再使用对应的kotlin插件版本,需要注意的是,这里仅是kotlin插件的版本,和kotlin语言的版本并非完全一一对应。我们通常关注的是kotlin插件的版本,很少去关注kotlin语言的版本。

Gradle版本kotlin插件版本kotlin语言版本
5.01.3.101.3
5.11.3.111.3
5.21.3.201.3
5.31.3.211.3
5.51.3.311.3
5.61.3.411.3
6.01.3.501.3
6.11.3.611.3
6.31.3.701.3
6.41.3.711.3
6.51.3.721.3
6.81.4.201.3
7.01.4.311.4
7.21.5.211.4
7.31.5.311.4
7.51.6.211.4
7.61.7.101.4
8.01.8.101.8
8.21.8.201.8

我不知道为什么kotlin插件的开发者对版本号的尾数0和1这么热衷,有谁来告诉我?难道是为了敬畏0和1吗?

我们来举几个🌰(栗子)

例子1: 这是一个很明显的Gradle编译错误。

Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.7.1, expected version is 1.5.1.

解决方案: 按照要求升级kotlin插件版本从1.5.1到1.7.1,即可解决。比如我给它升级到1.7.10。

ext.kotlin_version = '1.7.10'

例子2: 另外也是一个升级kotlin插件版本的编译错误,发生在Gradle8.x。

Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

解决方案: 在settings.gradle.kts加入以下代码。

pluginManagement {
    resolutionStrategy {
        if (requested.id.namespace == "org.jetbrains.kotlin") {
            def kotlin_version = "1.8.10"
            useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
        }
    }
}

并在app模块的build.gradle.kts加入以下代码。

implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.10")

例子3: 如果项目比较古老,也可能发生这个编译错误。

A problem was found with the configuration of task ':app:createReleaseApkListingFileRedirect' (type 'ListingFileRedirectTask').

  • In plugin 'com.android.internal.version-check' type 'com.android.build.gradle.internal.tasks.ListingFileRedirectTask' property 'listingFile' specifies file '/Users/dora/Desktop/DoraSample/app/release/output-metadata.json' which doesn't exist.

解决方案: 去掉以下代码,使用新的gradle生成apk文件名规则的配置。

android.applicationVariants.all {
    variant ->
        if (variant.buildType.name == "release") {
            variant.getPackageApplication().outputDirectory = new File(project.rootDir
                    .absolutePath + "/apk/")
            variant.outputs.all {
                outputFileName = "doramusic_${defaultConfig.versionName}_${defaultConfig.versionCode}.apk"
            }
        }
}

例子4:

JDK从8升到11,报以下编译错误

Unable to load class 'javax.xml.bind.JAXBException'.

解决方案:

dependencies {
    classpath 'com.android.tools.build:gradle:7.1.2'
}

例子5:

'compileAlphaDebugJavaWithJavac' task (current target is 11) and 'kaptGenerateStubsAlphaDebugKotlin' task (current target is 19) jvm target compatibility should be set to the same Java version.

解决方案:

compileOptions {
    sourceCompatibility(JavaVersion.VERSION_19)
    targetCompatibility(JavaVersion.VERSION_19)
}

总结

编译环境导致的问题远不止这些,所以说Gradle的坑很多。所以就导致很多的初学者,被这样的坑所劝退。但我想告诉大家,其实Gradle的坑并不可怕,可怕的是你并不知道要去看官方文档。我这里强烈推荐使用kts编写gradle的编译脚本。这样做的好处是有代码提示,而且方便我们研究相关类。我们可以研究它的一些Scope类以及与编译相关的配置类,这样有助于我们更好地驾驭Gradle脚本,让Android编译畅通无阻。掌握好Gradle,同时也可以让我们在编译的时候做更多事情,让我们的构建过程更加灵活和自动化。最后祝你好运,再也不担心Gradle的坑!另外附上官方文档地址,docs.gradle.org/current/use… ,有空一定记得去看。