Jetpack ViewModel
- ViewModel用来存储和管理UI相关数据,在生命周期内的一种有意识的方式。
- 解决3个问题:
- 通常我们通过
onSaveInstanceState()
恢复一些可序列化的小的数据,大数据比较bitmap就不管了 - UI控制器需要异步调用,这可能需要一段时间才能恢复。(destroy销毁)
- UI控制器主要的目的是显示UI数据,反映用户行为,处理与OS的通信,比如权限等。网络请求,数据库昂文,所以需要将逻辑从UI控制器中分离。
- 通常我们通过
1. 实现VM
class MyViewModel: ViewModel() {
private lateinit var users: MutableLiveData<List<User>>
fun getUsers(): LiveData<List<User>> {
if (!::users.isInitiabized) {
users = MutableLiveData()
loadUsers()
}
return users
}
// 异步获取users
private fun loadUsers() {}
}
// 使用
val model = ViewModelProviders.of(getContext()).get(MyViewModel::class.java)
model.getUsers().observe(getContext(), Observer<List<User>>) {Users -> // updata UI })
2. VM的生命周期
- ViewModel Scope贯穿Activity整个生命周期,直到Finished后系统会调用ViewModel的onCleared()
3. 在Fragment直接共享数据
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(saveInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java) ?: throw Exception("Invalid Activity") itemSelector.setOnClickListener {item -> // update UI }
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java) } ?. throw Exception("Invalid Activity") model.selected.observe(this, Observer<Item> { item -> // update UI })
}
}
}
该方法具有如下优点
- Activity不需要做任何事情,也不需要了解这种沟通
- 除了
SharedViewModel
外,Fragment不需要彼此了解,如果其中一个Fragment销毁,也另一个仍然可以继续工作 - 每个Fragment都有自己的生命周期,不受另一个影响。如果一个Fragment替换为别的Fragment,也没有任何问题。
4. 用VM替换Loaders
- 使用ViewModel与Room和LiveData一起替换
CursorLoader
5. 其他资源
dataBinding {
enabled =true
}