Skip to content

当在 Jetpack Compose 中使用 Room 数据库时,你可以充分利用 Compose 的声明式 UI 和 Room 的持久化数据管理能力,来构建具有响应式特性的应用程序。本文将为你提供一个完整的 Room 在 Compose 中使用的示例,以帮助你了解如何集成这两个强大的库。

步骤一:添加依赖

首先,在项目的 build.gradle 文件中添加 Room 的依赖:

implementation "androidx.room:room-runtime:2.4.0"
kapt "androidx.room:room-compiler:2.4.0"
implementation "androidx.room:room-runtime:2.4.0"
kapt "androidx.room:room-compiler:2.4.0"

步骤二:定义实体类

创建 Room 数据库的实体类,这些实体类将映射到数据库中的表。

kotlin
@Entity(tableName = "task_table")
data class Task(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val title: String,
    val description: String,
)
@Entity(tableName = "task_table")
data class Task(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val title: String,
    val description: String,
)

步骤三:创建DAO接口

创建用于访问数据库的 DAO(Data Access Object)接口。

kotlin
@Dao
interface TaskDao {
    @Query("SELECT * FROM task_table")
    fun getAllTasks(): Flow<List<Task>>

    @Insert
    suspend fun insertTask(task: Task)
}
@Dao
interface TaskDao {
    @Query("SELECT * FROM task_table")
    fun getAllTasks(): Flow<List<Task>>

    @Insert
    suspend fun insertTask(task: Task)
}

步骤四:创建Room数据库

创建 Room 数据库,将实体类和 DAO 接口与数据库关联。

kotlin
@Database(entities = [Task::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun taskDao(): TaskDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}
@Database(entities = [Task::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun taskDao(): TaskDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

步骤五:创建Repository

创建一个 Repository,用于将数据库操作封装起来,提供给 ViewModel 使用。

kotlin
class TaskRepository @Inject constructor(private val taskDao: TaskDao) {

    fun getAllTasks(): Flow<List<Task>> {
        return taskDao.getAllTasks()
    }

    suspend fun insertTask(task: Task) {
        taskDao.insertTask(task)
    }
}
class TaskRepository @Inject constructor(private val taskDao: TaskDao) {

    fun getAllTasks(): Flow<List<Task>> {
        return taskDao.getAllTasks()
    }

    suspend fun insertTask(task: Task) {
        taskDao.insertTask(task)
    }
}

步骤六:创建ViewModel

创建一个 ViewModel,用于管理数据和与数据库交互。

kotlin
@HiltViewModel
class TaskViewModel @Inject constructor(private val taskRepository: TaskRepository) : ViewModel() {

    val allTasks: Flow<List<Task>> = taskRepository.getAllTasks()

    fun insertTask(task: Task) {
        viewModelScope.launch {
            taskRepository.insertTask(task)
        }
    }
}
@HiltViewModel
class TaskViewModel @Inject constructor(private val taskRepository: TaskRepository) : ViewModel() {

    val allTasks: Flow<List<Task>> = taskRepository.getAllTasks()

    fun insertTask(task: Task) {
        viewModelScope.launch {
            taskRepository.insertTask(task)
        }
    }
}

步骤七:在Composable中使用Room数据

在 Composable 函数中使用 Hilt 的 hiltViewModel() 函数来获取 ViewModel,并从 ViewModel 中获取 Room 数据。

kotlin
@Composable
fun TaskListScreen(viewModel: TaskViewModel = hiltViewModel<TaskViewModel>()) {
    val tasks by viewModel.allTasks.collectAsState()

    Column {
        // 显示任务列表
        LazyColumn {
            items(tasks) { task ->
                Text(text = task.title)
            }
        }

        // 添加任务按钮
        Button(onClick = {
            viewModel.insertTask(Task(title = "New Task", description = "Description"))
        }) {
            Text("Add Task")
        }
    }
}
@Composable
fun TaskListScreen(viewModel: TaskViewModel = hiltViewModel<TaskViewModel>()) {
    val tasks by viewModel.allTasks.collectAsState()

    Column {
        // 显示任务列表
        LazyColumn {
            items(tasks) { task ->
                Text(text = task.title)
            }
        }

        // 添加任务按钮
        Button(onClick = {
            viewModel.insertTask(Task(title = "New Task", description = "Description"))
        }) {
            Text("Add Task")
        }
    }
}

结论

通过将 Room 数据库与 Jetpack Compose 集成,你可以创建具有响应式特性的应用程序,轻松管理和展示持久化数据。本文中的示例演示了 Room 在 Compose 中的完整使用过程,从定义实体类、创建 DAO 接口到最终在 Composable 中展示数据,希望能够帮助你更好地理解和应用这些功能。

参考资料:

https://developer.android.com/jetpack/androidx/releases/room#kts

https://developer.android.com/training/data-storage/room#kts

https://developer.android.com/courses/pathways/android-basics-compose-unit-6-pathway-2

https://developer.android.com/codelabs/basic-android-kotlin-compose-persisting-data-room#0