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

  3. 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.

  4. Enter data as the Module name

  5. Update the Package name to com.androidbyexample.movies.data

    Choosing New Module

  6. Press Finish

  7. Press Add to add the newly-created files to git

    Choosing New Module

Repeat for the repository module.

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

All code changes

CHANGED: build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.compose) apply false
    alias(libs.plugins.android.library) apply false
}
ADDED: data/.gitignore
/build
ADDED: data/build.gradle.kts
plugins {
    alias(libs.plugins.android.library)
}

android {
    namespace = "com.androidbyexample.movies.data"
    compileSdk {
        version = release(37)
    }

    defaultConfig {
        minSdk = 24

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

}

dependencies {
    implementation(libs.androidx.appcompat)
    implementation(libs.androidx.core.ktx)
    implementation(libs.material)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(libs.androidx.junit)
}
ADDED: data/src/androidTest/java/com/androidbyexample/movies/data/ExampleInstrumentedTest.kt
package com.androidbyexample.movies.data

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

/**
 * 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.movies.data.test", appContext.packageName)
    }
}
ADDED: data/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>

</manifest>
ADDED: data/src/test/java/com/androidbyexample/movies/data/ExampleUnitTest.kt
package com.androidbyexample.movies.data

import org.junit.Assert.assertEquals
import org.junit.Test

/**
 * 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 = "9.2.1"
coreKtx = "1.19.0"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.11.0"
activityCompose = "1.13.0"
kotlin = "2.4.0"
composeBom = "2026.06.01"
navigation = "1.1.4"
material3AdaptiveNav3 = "1.3.0-rc01"
appcompat = "1.7.1"
material = "1.14.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }

androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "navigation" }
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "navigation" }
androidx-material3-adaptive-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "material3AdaptiveNav3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
android-library = { id = "com.android.library", version.ref = "agp" }
ADDED: repository/.gitignore
/build
ADDED: repository/build.gradle.kts
plugins {
    alias(libs.plugins.android.library)
}

android {
    namespace = "com.androidbyexample.movies.repository"
    compileSdk {
        version = release(37)
    }

    defaultConfig {
        minSdk = 24

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

}

dependencies {
    implementation(libs.androidx.appcompat)
    implementation(libs.androidx.core.ktx)
    implementation(libs.material)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(libs.androidx.junit)
}
ADDED: repository/src/androidTest/java/com/androidbyexample/movies/repository/ExampleInstrumentedTest.kt
package com.androidbyexample.movies.repository

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

/**
 * 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.movies.repository.test", appContext.packageName)
    }
}
ADDED: repository/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>

</manifest>
ADDED: repository/src/test/java/com/androidbyexample/movies/repository/ExampleUnitTest.kt
package com.androidbyexample.movies.repository

import org.junit.Assert.assertEquals
import org.junit.Test

/**
 * 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 {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
}
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "Movies"
include(":app")
include(":data")
include(":repository")