Migrate your Multi-Module App to AGP and Gradle 8.0 with Android Studio Flamingo

BHAVNA THACKER
4 min readJul 7, 2023

--

Migrate your Multi-Module app to AGP and Gradle 8.0 with Android Studio Flamingo

Now that Android Studio Flamingo is stable, I would like to share my experience regarding migrating a Multi-module app for Android Studio Flamingo with latest version of AGP and Gradle.

Note: You can use AGP Upgrade Assistant . It is also possible to handle these changes manually. In either case, it is good to know what are these changes and benefit of it.

Update AGP

Android Studio Flamingo suggests migrating to AGP version is 8.0. If you are wondering why? then here is the official link.

The Android Studio build system is based on Gradle, and the Android Gradle plugin (AGP) adds several features that are specific to building Android apps.

At the time of writing this post, latest AGP version is 8.0.2. You can check latest version here.

https://developer.android.com/studio/releases

Update Gradle

There is also a compatible version of Gradle required for each AGP version. See the link here.

https://developer.android.com/build/releases/gradle-plugin

Now, that you updated AGP and Gradle to 8.0, you may need several changes in your app build.

NOTE: The below list of changes are not exhaustive as depending on your app configuration, you may need additional changes. However, I have tried to cover all that I came across.

Move package from Manifest to Build files:

This change solves a lot of confusion around applicationId and namespace

There is no package attribute now and namespace property lets you refactor your app’s code and resources (R classes, BuildConfig) without affecting your applicationId .

applicationId identifies your app on Google Play Store.

NOTE: In Multi-module app, you need to do below changes for all modules apart from the main app module.

Remove package attribute from Manifest:

// Android manifest Before:
<manifest xmlns:android=”http://schemas.android.com/apk/res/android"
xmlns:tools=”http://schemas.android.com/tools"
package=”com.example.myapp” >
// Android manifest After:
<manifest xmlns:android=”http://schemas.android.com/apk/res/android"
xmlns:tools=”http://schemas.android.com/tools">

Add namespace in build.gradle/build.gradle.kts

// Module build.gradle Before: 
android {
compileSdk 34..
}

// Module build.gradle After:
android {
namespace 'com.example.myapp'
compileSdk 34…
}

OR

// Module build.gradle.kts Before:
android {
compileSdk = 34..
}

// Module build.gradle.kts After:
android {
namespace = "com.example.myapp"
compileSdk = 34…
}

From AGP 8.0, R classes are not transitive by default for library modules

From AGP 8.0, In the gradle.properties file, the default value of android.nonTransitiveRClass istrue when not specified, and thus becomes the default.

This means each R class only includes resources from its own module and not from dependencies.

So when referencing resources, you must use fully qualified namespaced calls. e.g.:

//Library Module
val icon = R.drawable.ic_next // Will not work if ic_next resides in a dependent module
val icon = com.example.core.R.drawable.ic_next // Will work this way

To avoid doing this manually, you can try below:

Go to Refactor > Migrate to Non-Transitive R Classes.

This change reduces size of R class for a module and hence some improvement in build time.

Enable BuildConfig explicitly if you need

If you use BuildConfig class in your module, you need to enable it explicitly as below, otherwise the BuildConfig file isn’t automatically generated now.

// Module's build.gradle OR build.gradle.kts
android {
buildFeatures {
//Enable by adding below line for a module that needs it
buildConfig = true
}
}

In multi-module app, do not add above line to a module, unless your module needs it. app module is though very likely to need it.

JDK 17 required to run AGP 8.0

See official link here.

Android Studio Flamingo bundles JDK 17 and configures Gradle to use it by default so most of Android Studio users don’t need to make any configuration changes to their projects.

If you are manually setting the JDK version used by AGP in your build.gradle like below then change it as to JDK 17:

app/build.gradle & all library module's build.gradle where it is set:

BEFORE:

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_XYZ
targetCompatibility JavaVersion.VERSION_XYZ
}
}

AFTER:

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
app/build.gradle & all library module's build.gradle where it is set:

BEFORE:

android {
kotlin {
jvmToolchain(11)
}
}

AFTER:

android {
kotlin {
jvmToolchain(17)
}
}
app/build.gradle & all library module's build.gradle where it is set:

BEFORE:

android {
kotlinOptions {
jvmTarget = "11"
}
}

AFTER:

android {
kotlinOptions {
jvmTarget = "17"
}
}

If you are using Version Catalogs in your app and now updating to Gradle 8.0, then remove below line from your project’s settings.gradle.

//REMOVE below line else you get build error
enableFeaturePreview(“VERSION_CATALOGS”)

This is because versionCatalogs block was promoted to a stable feature since Gradle 7.4-rc-1. See 7.4-rc-1 Release Notes.

If you are using Mockito Library for your Unit Tests, then with JDK 17 upgrade, your tests will fail if you are mocking a sealed class or a sealed Interface.

You need to replace your mock like below:

sealed interface A
interface B: A

val mockObj = mock<A>() // This will fail
val mockObj = mock<B>() // Change to this so tests pass

That’s it folks! Hope this helps you in migrating a real world app to latest version of Android Studio and AGP/Gradle etc.

References:

--

--

BHAVNA THACKER

Android GDE. Youtuber — LearnAndroid. Senior Android Engineer @MEGA. FPE @raywenderlich.