抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

因为一个 warning 将 gradle 更新至 AGP8.0

背景

闲来无事,更新了 IDE 到 Hedgehog ,看了一眼编译警告,看到了这么一行:

'compileDebugJavaWithJavac' task (current target is 11) and 'kaptGenerateStubsDebugKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.

经过了解,其实是 kotlinOptions 配置不再生效导致的,不知道在什么版本,kotlin 的配置方式变了。

android {

    compileOptions {
     sourceCompatibility JavaVersion.VERSION_11
     targetCompatibility JavaVersion.VERSION_11
    }

    //kotlinOptions {
    // jvmTarget = "11"
    //}

    kotlin {
     jvmToolchain(11)
    }
}

一顿操作下来,warning 没了,想着完美解决了,但是看了看项目,首先是右下角多了一个弹窗,内容如下:

Android Gradle plugin version 7.3.1 has an upgrade available. Start the AGP Upgrade Assistant to update this project's AGP version.

其次,以往 ext 方式的 lib依赖,全部报 warning:

Unrecognized dependency notation

在依赖那边看官方的警告分析找到了一个关键词:Version Catalogs。

其中链接:https://docs.gradle.org/current/userguide/platforms.html ,大致也就明白了,增加了新的规范,既然如此,整吧。

AGP8 Version Catalogs

Android 的依赖管理,有一个发展过程。一般是 ext 扩展字段形式,用起来类似 implementation project.lib.compose_ui 这种,缺点比如无法跳转引用,不会提示版本更新,优点就是简单。

其他的就是 buildSrc ,到 buildSrc + Kotlin DSL,本质上就是 groovy 造的插件轮子用 kotlin 再造,后来还有一个更魔幻的 Gradle Composite builds。好在Gradle 8,官方指了明路,所以直接跳 AGP8 官方推荐的方式 version catalogs

PS:虽然说是 AGP8 但是从 Gradle 7.0 就开始了,但是那时候还是实验性特性,需要使用 enableFeaturePreview('VERSION_CATALOGS') 进行开启,AG8 默认已开启。

变更

一些编译链的运行环境需要改为 IDE 推荐的 Java 17:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlin {
        jvmToolchain(17)
    }
}

相关 gradle 插件需要升级(推荐使用 菜单->Tools->AGP Upgrade Assistant):

#build.gradle
classpath "com.android.tools.build:gradle:8.1.1"

#gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip

不出意外,各模块 build.gradle 加上了 namespace,Sync 后编译不会通过,答案也放这里了,需要关几个 AGP8 默认开启的配置。

#gradle.properties

# 开启 buildconfig,不然找不到 BuildConfig android.defaults.buildfeatures.buildconfig=true
# 配置非传递性 R 类,开启后每个 module的产生的 R 文件会各自独立一个类引用多个R类很难受
android.nonTransitiveRClass=false
# R.id 的警告
android.nonFinalResIds=false
# 用不着的类会从dex移除 反射那种将会 crash,不要说用不着,Gson?
android.enableR8.fullMode=false

不出意外,应该可以正常运行,但这只是开始,依赖的 warning 还在。

使用 toml 进行依赖管理

这里有个前提条件,就是 versionCatalogs 这个块是 kotlin DSL ,所以需要将 setting.gradle 改为 setting.gradle.kts 。大概规律就是加(),单引号改双引号。详细的看官方:将 build 配置从 Groovy 迁移到 KTS

结果如下:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        gradlePluginPortal()
        mavenCentral()
        maven { setUrl("https://jitpack.io") } // 较大的变化
        jcenter() // Warning: this repository is going to shut down soon
    }
    //新的依赖方式
    versionCatalogs {
        create("libs") {
            from(files("./libs.versions.toml"))
        }
    }
}

rootProject.name = "Your app name."
include(":app")
include(":Resource")

其中的 versionCatalogs ,就是 DSL 化后增加的,这里也有一些讲究,比如 libs 是使用这个配置文件时的引用方式,用 libs.xxx 就能访问这个配置的某个属性,想要区分或者自定义就继续新增即可。

toml 配置文件写起来很简单,大致如下,有依赖共同版本和不需要共同版本的这里都放一份,自行区分 version.ref 与 version,一个是引用,一个是字符串。

[versions]
savedState = "1.2.1"

[libraries]
savedstate = { group = "androidx.savedstate", name = "savedstate", version.ref = "savedState" }
supportcompat = { group = "com.android.support", name = "support-compat", version = "28.0.0" }

将项目现有依赖都改成这种配置后,就可以在模块 build.gradle 中自由配置了:

dependencies {
    implementation libs.savedstate
}

如果不是想引用依赖,只是想用其中的一个版本数值,则可以这样用:

def saved_state = libs.versions.savedState.get() // "1.2.1"

其他的比如自定义插件的升级等,这里就不说了,主要是未涉及,相当成熟了,用起来吧~

参考

中文:

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

迁移到 Gradle 7.x 使用 Version Catalogs 管理依赖 

使用 Kotlin DSL 进行依赖管理

【Gradle7.0】依赖统一管理的全新方式,了解一下~

将 build 配置从 Groovy 迁移到 KTS

快速迁移 Gradle 脚本至 KTS

英文/官方:

Sharing dependency versions between projects

Configure a Gradle project

Migrate your build to version catalogs


本站由以下主机服务商提供服务支持:

0条评论

发表评论