Kotlinv2.4.0

Android 源集布局

新的 Android 源集布局在 Kotlin 1.8.0 中引入,并在 1.9.0 中成为默认布局。请参考本指南以了解弃用的布局与新布局之间的主要区别,以及如何迁移您的项目。

您无需执行所有建议,只需执行适用于您特定项目的建议即可。

检查兼容性

新布局要求使用 Android Gradle 插件 7.0 或更高版本,并且受 Android Studio 2022.3 及更高版本支持。请检查您的 Android Gradle 插件版本,并在必要时进行升级。

重命名 Kotlin 源集

如果适用,请按照以下模式重命名项目中的源集:

旧版源集布局新版源集布局
targetName + AndroidSourceSet.nametargetName + AndroidVariantType

{AndroidSourceSet.name}{KotlinSourceSet.name} 的映射关系如下:

旧版源集布局新版源集布局
mainandroidMainandroidMain
testandroidTestandroidUnitTest
androidTestandroidAndroidTestandroidInstrumentedTest

移动源文件

如果适用,请按照以下模式将源文件移动到新目录:

旧版源集布局新版源集布局
该布局具有额外的 /kotlin SourceDirectoriessrc/{KotlinSourceSet.name}/kotlin

{AndroidSourceSet.name}{包含的 SourceDirectories} 的映射关系如下:

旧版源集布局新版源集布局
mainsrc/androidMain/kotlin
src/main/kotlin
src/main/java
src/androidMain/kotlin
src/main/kotlin
src/main/java
testsrc/androidTest/kotlin
src/test/kotlin
src/test/java
src/androidUnitTest/kotlin
src/test/kotlin
src/test/java
androidTestsrc/androidAndroidTest/kotlin
src/androidTest/java
src/androidInstrumentedTest/kotlin
src/androidTest/java, src/androidTest/kotlin

移动 AndroidManifest.xml 文件

如果您的项目中包含 AndroidManifest.xml 文件,请按照以下模式将其移动到新目录:

旧版源集布局新版源集布局
src/{AndroidSourceSet.name}/AndroidManifest.xmlsrc/{KotlinSourceSet.name}/AndroidManifest.xml

{AndroidSourceSet.name}{AndroidManifest.xml 位置} 的映射关系如下:

旧版源集布局新版源集布局
mainsrc/main/AndroidManifest.xmlsrc/androidMain/AndroidManifest.xml
debugsrc/debug/AndroidManifest.xmlsrc/androidDebug/AndroidManifest.xml

检查 Android 与公共测试之间的关系

新的 Android 源集布局改变了 Android 仪器化测试(在新布局中重命名为 androidInstrumentedTest)与公共测试(common tests)之间的关系。

此前,androidAndroidTestcommonTest 之间的 dependsOn 关系是默认存在的。这意味着:

  • commonTest 中的代码在 androidAndroidTest 中可用。
  • commonTest 中的 expect 声明必须在 androidAndroidTest 中有对应的 actual 实现。
  • commonTest 中声明的测试也会作为 Android 仪器化测试运行。

在新的 Android 源集布局中,默认不再添加 dependsOn 关系。如果您希望保留之前的行为,请在 build.gradle.kts 文件中手动声明以下关系:

kotlin
kotlin {
// ...
    sourceSets {
        val commonTest by getting
        val androidInstrumentedTest by getting {
            dependsOn(commonTest)
        }
    }
}

调整 Android flavor 的实现

此前,Kotlin Gradle 插件会预先创建与 Android 源集相对应的源集,这些源集包含 debugrelease 构建类型或自定义变体(如 demofull)。这使得可以通过 val androidDebug by getting { ... } 之类的表达式访问这些源集。

新的 Android 源集布局利用 Android 的 onVariants 来创建源集。这导致此类表达式失效,并引发类似 org.gradle.api.UnknownDomainObjectException: KotlinSourceSet with name 'androidDebug' not found 的错误。

要解决此问题,请在 build.gradle.kts 文件中使用新的 invokeWhenCreated() API:

kotlin
kotlin {
// ...
    @OptIn(ExperimentalKotlinGradlePluginApi::class)
    sourceSets.invokeWhenCreated("androidFreeDebug") {
// ...
    }
}