Movies Database
Add new modules
Note
You will not need to add any code manually in this step. The displayed diffs are here to show you what gets added when you add the new modules.
We start with the basic Movie UI created in Initial Movies UI.
The first thing we need to do is add two modules, data
and repository
. You can name these anything you'd like, but I recommend these names as they represent what you're doing pretty well.
To create these modules:
- Right-click the top-level project in the Project view
- Choose New -> Module
- Select the Android Library template
!!! note
We choose **Android Library** here because we'll be using Room, which requires Android dependencies such as
a context to create the database instance. If the module did not have any Android dependencies, we could
instead create a **Java or Kotlin Library** module.
- Enter
data
as the Module name - Update the Package name to lastname.firstname.appname.data
- Press Finish
- Press Add to add the newly-created files to git
Repeat for the repository
module.
Delete the libs
directory in each module (app
, data
, and repository
). This is used to host local copies of jars rather than import them from external repositories or other modules in your project.
Note that settings.gradle.kts
(at the top level of your project) has been updated to add the two new modules. This is how gradle (and Android Studio) know that these are modules it needs to build.
include(":app")
include(":data")
include(":repository")
Code Changes
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} true // Needed to make the Suppress annotation work for the plugins block
ADDED: /data/build.gradle.kts
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixedplugins { alias(libs.plugins.androidLibrary) alias(libs.plugins.kotlinAndroid)}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) testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.espresso.core)}
ADDED: /data/src/androidTest/java/com/androidbyexample/movie/data/ExampleInstrumentedTest.kt
package com.androidbyexample.movie.dataimport androidx.test.platform.app.InstrumentationRegistryimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Testimport org.junit.runner.RunWithimport org.junit.Assert.*/** * Instrumented test, which will execute on an Android device. * * See [testing documentation](http://d.android.com/tools/testing). */@RunWith(AndroidJUnit4::class)class ExampleInstrumentedTest { @Test fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.androidbyexample.movie.data.test", appContext.packageName) }}
ADDED: /data/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"></manifest>
ADDED: /data/src/test/java/com/androidbyexample/movie/data/ExampleUnitTest.kt
package com.androidbyexample.movie.dataimport org.junit.Testimport org.junit.Assert.*/** * Example local unit test, which will execute on the development machine (host). * * See [testing documentation](http://d.android.com/tools/testing). */class ExampleUnitTest { @Test fun addition_isCorrect() { assertEquals(4, 2 + 2) }}
CHANGED: /gradle/libs.versions.toml
[versions] agp = "8.2.0-beta03" kotlin = "1.9.10" 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" [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" } [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" }
ADDED: /repository/build.gradle.kts
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixedplugins { alias(libs.plugins.androidLibrary) alias(libs.plugins.kotlinAndroid)}android { namespace = "com.androidbyexample.movie.repository" 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) testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.espresso.core)}
ADDED: /repository/src/androidTest/java/com/androidbyexample/movie/repository/ExampleInstrumentedTest.kt
package com.androidbyexample.movie.repositoryimport androidx.test.platform.app.InstrumentationRegistryimport androidx.test.ext.junit.runners.AndroidJUnit4import org.junit.Testimport org.junit.runner.RunWithimport org.junit.Assert.*/** * Instrumented test, which will execute on an Android device. * * See [testing documentation](http://d.android.com/tools/testing). */@RunWith(AndroidJUnit4::class)class ExampleInstrumentedTest { @Test fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.androidbyexample.movie.repository.test", appContext.packageName) }}
ADDED: /repository/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"></manifest>
ADDED: /repository/src/test/java/com/androidbyexample/movie/repository/ExampleUnitTest.kt
package com.androidbyexample.movie.repositoryimport org.junit.Testimport org.junit.Assert.*/** * Example local unit test, which will execute on the development machine (host). * * See [testing documentation](http://d.android.com/tools/testing). */class ExampleUnitTest { @Test fun addition_isCorrect() { assertEquals(4, 2 + 2) }}
CHANGED: /settings.gradle.kts
pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "MovieDb" include(":app")