Movies Database

Add Room dependencies

Next we add the Room dependencies and the Kotlin Symbol Processor (KSP).

The Kotlin Symbol Processor is a compiler plugin that loads "symbol processors". These processors examine your source code and create new classes as needed, typically looking at annotations in your code. The Room compiler is a symbol processor that generates code based on Room annotations like @Entity and @Database.

We add the KSP and Room versions, Room compiler and dependencies and KSP plugin to our version catalog.

Note

Version compatibility can start to get messy as we add more dependencies and plugins. As I'm writing this, the latest version of Kotlin was 1.9.10, which matches the Compose Compiler Plugin version 1.5.3 (see Compose to Kotlin Compatibility Map), and the latest version of KSP was 1.9.0-1.0.13. Note the "1.9.0" part of that version...

The Kotlin compiler's plugin API was not stable as I wrote this. As the compiler plugin API evolves, compiler plugins must change the API they use. The version convention of the KSP plugin indicates which version of the compiler it works with. In this case, 1.9.0 doesn't match Kotlin 1.9.10.

So my only choice here is to back down my Kotlin version to 1.9.0, which then means I need to consult Compose to Kotlin Compatibility Map which requires Compose compiler plugin 1.5.2.

(I'm working on this exact issue, trying to make it easier to determine the correct set of version requirements...)

We want to specify the version of plugins to use in one place, in case they're used in multiple modules. We do this by adding the plugin to the top build.gradle.kts but don't apply it (so it doesn't actually do anything there other than specify the version to use).

Then we tell the data module to apply the KSP plugin, and set up the Room dependencies. The implementation dependencies will be available for compilation and included in the built application. The ksp dependency will only be used by KSP as a symbol processor to generate code based on the Room annotations.

We're only using Room in the data module, so we don't need to add these dependencies in the repository module's build.gradle.kts file.

Remember after changing the version catalog and gradle build files to re-synchronize by pressing the elephant icon (or the "Sync Now" link at the top of the build files)!

At this point, nothing will visibly change in the application, but it should still build.

Code Changes

CHANGED: /app/build.gradle.kts
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.kotlinAndroid)
}

kotlin { jvmToolchain(17) }
android { namespace = "com.androidbyexample.movie" compileSdk = 34 defaultConfig { applicationId = "com.androidbyexample.moviedb" minSdk = 24 targetSdk = 34 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) }
} buildFeatures { compose = true }
composeOptions { // kotlinCompilerExtensionVersion = "1.5.3" kotlinCompilerExtensionVersion = "1.5.2" } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } } dependencies { implementation(libs.core.ktx) implementation(libs.lifecycle.runtime.ktx) implementation(libs.activity.compose) implementation(platform(libs.compose.bom)) implementation(libs.ui) implementation(libs.ui.graphics) implementation(libs.ui.tooling.preview) implementation(libs.material3) testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(platform(libs.compose.bom)) androidTestImplementation(libs.ui.test.junit4) debugImplementation(libs.ui.tooling) debugImplementation(libs.ui.test.manifest) }
CHANGED: /build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
    alias(libs.plugins.androidApplication) apply false
    alias(libs.plugins.kotlinAndroid) apply false
    alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.ksp) apply false
} true // Needed to make the Suppress annotation work for the plugins block
CHANGED: /data/build.gradle.kts
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
    alias(libs.plugins.androidLibrary)
    alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.ksp)
} android { namespace = "com.androidbyexample.movie.data" compileSdk = 34 defaultConfig { minSdk = 24 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { implementation(libs.core.ktx) implementation(libs.appcompat) implementation(libs.material)
implementation(libs.room.runtime) implementation(libs.room.ktx) ksp(libs.room.compiler)
testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.espresso.core) }
CHANGED: /gradle/libs.versions.toml
[versions]
agp = "8.2.0-beta03"
//kotlin = "1.9.10"kotlin = "1.9.0"core-ktx = "1.12.0"
junit = "4.13.2"
androidx-test-ext-junit = "1.1.5"
espresso-core = "3.5.1"
lifecycle-runtime-ktx = "2.6.2"
activity-compose = "1.7.2"
compose-bom = "2023.09.00"
appcompat = "1.6.1"
material = "1.9.0"
room = "2.5.2"ksp = "1.9.0-1.0.13"
[libraries] core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" } activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity-compose" } compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } ui = { group = "androidx.compose.ui", name = "ui" } ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } material3 = { group = "androidx.compose.material3", name = "material3" } appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" }
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
[plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } androidLibrary = { id = "com.android.library", version.ref = "agp" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }