Jetpack Compose 配合 Room, ViewModel 操作数据库

更新日期: 2021-09-21 阅读次数: 4513 字数: 398 分类: Android

放到一个文件中?

感觉 entity, dao, repository 可以放到一个文件中, 但是 database 还是需要独立出来,因为一个 database 可能包含多个 entity。

这样找 entity 进行修改时比较方便。

为何需要 ViewModel

屏幕在横屏、竖屏旋转切换时,Activity 会被重建。如果临时状态数据存储在 Activity 中, 横竖屏切换后,会导致状态重置,例如计数器重置,出现 bug。

所以,需要一个能保存状态的机制,于是有了 ViewModel。

为何需要 ViewModelProvider.Factory

在 Todo Demo App 中,可以看到,除了定义一个 ViewModel 之外,还定义了一个 ViewModelFactory。

class TodoViewModelFactory(
    private val application: Application
) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        @Suppress("UNCHECKED_CAST")
        if (modelClass.isAssignableFrom(TodoViewModel::class.java)) {
            return TodoViewModel(application) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

HomeScreen Composable 中由 ViewModelFactory 初始化一个 ViewModel,然后传给对应组件。

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun HomeScreen(navController: NavController) {
	val mTodoViewModel: TodoViewModel = viewModel(
		factory = TodoViewModelFactory(context.applicationContext as Application)
	)
	val items = mTodoViewModel.readAllData.observeAsState(listOf()).value
	
	Column(
        modifier = Modifier.padding(16.dp)
    ) {
        TodoList(list = items, mTodoViewModel = mTodoViewModel)
    }
}

ViewModelFactory 的意义何在?

  • 能保证 ViewModel 只有一个实例。例如,Activity 反复被重建时,应该只存在一个 ViewModel 实例。
  • 能提供初始化参数。使用 ViewModelProvider.of 也能达到一个实例的效果,但是没法提供初始化参数。例如,传递初始化值,或者本例中的 application。

参考

tags: Jetpack Compose ViewModel android room

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式