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:

  1. Right-click the top-level project in the Project view
  2. Choose New -> Module

Choosing New Module

  1. 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.
  1. Enter data as the Module name
  2. Update the Package name to lastname.firstname.appname.data

Choosing New Module

  1. Press Finish
  2. Press Add to add the newly-created files to git

Choosing New Module

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")