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

文章目录

    放到一个文件中?

    感觉 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。

    参考

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式