Android source set layout
The new Android source set layout was introduced in Kotlin 1.8.0 and became the default in 1.9.0. Follow this guide to understand the key differences between the deprecated and the new layouts, as well as how to migrate your projects.
tip
You don't need to implement all the suggestions, only those that are applicable to your particular projects.
The new layout requires Android Gradle plugin 7.0 or later and is supported in Android Studio 2022.3 and later. Check your version of the Android Gradle plugin and upgrade if necessary.
If applicable, rename the source sets in your project, following this pattern:
Previous source set layout | New source set layout |
---|---|
|
|
{AndroidSourceSet.name}
maps to {KotlinSourceSet.name}
as follows:
Previous source set layout | New source set layout | |
---|---|---|
main | androidMain | androidMain |
test | androidTest | androidUnitTest |
androidTest | androidAndroidTest | androidInstrumentedTest |
If applicable, move your source files to the new directories, following this pattern:
Previous source set layout | New source set layout |
---|---|
The layout had additional |
|
{AndroidSourceSet.name}
maps to {SourceDirectories included}
as follows:
Previous source set layout | New source set layout | |
---|---|---|
main | src/androidMain/kotlin src/main/kotlin src/main/java | src/androidMain/kotlin src/main/kotlin src/main/java |
test | src/androidTest/kotlin src/test/kotlin src/test/java | src/androidUnitTest/kotlin src/test/kotlin src/test/java |
androidTest | src/androidAndroidTest/kotlin src/androidTest/java | src/androidInstrumentedTest/kotlin src/androidTest/java, src/androidTest/kotlin |
If you have the AndroidManifest.xml
file in your project, move it to the new directory, following this pattern:
Previous source set layout | New source set layout |
---|---|
src/{AndroidSourceSet.name}/AndroidManifest.xml | src/{KotlinSourceSet.name}/AndroidManifest.xml |
{AndroidSourceSet.name}
maps to {AndroidManifest.xml location}
as follows:
Previous source set layout | New source set layout | |
---|---|---|
main | src/main/AndroidManifest.xml | src/androidMain/AndroidManifest.xml |
debug | src/debug/AndroidManifest.xml | src/androidDebug/AndroidManifest.xml |
The new Android source set layout changes the relationship between Android-instrumented tests (renamed to androidInstrumentedTest
in the new layout) and common tests.
Previously, the dependsOn
relationship between androidAndroidTest
and commonTest
was the default. It meant the following:
The code in
commonTest
was available inandroidAndroidTest
.expect
declarations incommonTest
had to have correspondingactual
implementations inandroidAndroidTest
.Tests declared in
commonTest
were also running as Android instrumented tests.
In the new Android source set layout, the dependsOn
relationship is not added by default. If you prefer the previous behavior, manually declare the following relationship in your build.gradle.kts
file:
kotlin {
// ...
sourceSets {
val commonTest by getting
val androidInstrumentedTest by getting {
dependsOn(commonTest)
}
}
}
Previously, the Kotlin Gradle plugin eagerly created source sets that corresponded to Android source sets containing debug
and release
build types or custom flavors like demo
and full
. It made the source sets accessible by using expressions like val androidDebug by getting { ... }
.
The new Android source set layout makes use of Android's onVariants
to create source sets. It makes such expressions invalid, leading to errors like org.gradle.api.UnknownDomainObjectException: KotlinSourceSet with name 'androidDebug' not found
.
To work around that, use the new invokeWhenCreated()
API in your build.gradle.kts
file:
kotlin {
// ...
@OptIn(ExperimentalKotlinGradlePluginApi::class)
sourceSets.invokeWhenCreated("androidFreeDebug") {
// ...
}
}
Thanks for your feedback!