ViewModel

ViewModel保护数据不被销毁,
LiveData实时监听数据的变化

ViewModel

就是保证数据的稳定性

当界面旋转时, activity 会销毁再重建

ViewModel 属于 lifecycle(生命周期感知型组件)中的一员,通常与 LiveData 、 DataBinding 一起使用,它们是 MVVM 架构 的重要成员。
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。
viewMode1 类让数据可在发生屏幕旋转等配置更改后继续留存。

ViewModel是一个用来 管理UI数据处理屏幕旋转等配置变化时的数据保存和恢复 组件。

ViewModel 的生命周期长,应该存放一些不希望因为界面旋转、跳转而丢失的数据(长时间保存的数据)

使用步骤

1.导入依赖

1
2
3
//ViewModel
implementation"androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1") //Kotlin版本要加括号

2.定义 ViewModel 的实现类 ——> 管理数据

1
2
3
4
5
6
7
class MainViewModel:ViewModel(){
var number:Int = 0

fun addOne(){
number++
}
}

AndroidViewModel 是 ViewModel 的一个子类,它接收 Application 作为参数,可以用于在 ViewModel 中获取应用的 Context ,通常用于需要应用 Context 的场景

1
2
3
4
5
6
7
import android.app.Application
import androidx.lifecycle.AndroidViewModel

class MyAndroidViewModel(application: Application) : AndroidViewModel(application) {
// 在这里可以定义ViewModel需要管理的数据和方法
}

3.使用 ViewModelProvider 创建 ViewModel 子类对象

和 activity 产生关系
创建 ViewModel 对象

方式一:
OnCreate() 中创建对象

viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

private var viewMode = ViewModelProvider(owner 这个 ViewModel 观察谁的生命周期).get(需要创建哪个 ViewModel)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MainActivity : AppCompatActivity() {
private lateinit var binding:ActivityMainBinding
private lateinit var viewModel: MainViewModel


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}

}

方式二:
private val mViewModel: MainViewModel by viewModels()

viewModels() 是 ComponentActivity 的一个扩展方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//最终版本
class MainActivity : AppCompatActivity() {
private lateinit var binding:ActivityMainBinding

private val mViewModel: MainViewModel by viewModels()


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)


}

}

Fragment 与 Activity 之间共享 ViewModel

保证使用的是同一个 ViewModel 对象

Activity中

1
private val viewModel: MainViewModel by viewModels()

Fragment中

1
val viewModel:MainViewModel by activityViewModels()

Fragment 之间共享 ViewModel

都使用

Fragment中

1
val viewModel:MainViewModel by activityViewModels()

LiveData

LiveData 是一种可观察的数据存储器类。
与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。
这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
(使用给数据,当数据需要给外部观察,即某一数据一发生变化,外部就得时时刻刻知道,第一时间知道)

在MainViewModel中

  1. 导入依赖
1
2
//LiveData  
implementation"androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
  1. 定义一个被观察的数据,操作数据
    postValue() 更新
    getValue() 获取
1
2
3
4
5
6
7
8
9
10
11
12
13
class SharedViewModel:ViewModel(){

var number: MutableLiveData<Int> = MutableLiveData( value: 0)

//ViewModel 中添加外部访问的方法
fun getNumber() = number.value!!

fun addOne(){
val result = number.value!! + 1
number.postValue(result) //写入新的值 postValue(此时观察者就会收到更新的消息)
}

}
  1. 使用者观察数据

MainActivity中
观察数据变化

mViewModel.number. observe (owner: LifecycleOwner 谁观察,observer: (Int!)-> Unit有变化要做什么)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//监听 并实现Observe接口的onChange方法
//当数据改变时,最终调用了观察者的onChange方法,并传递数据过去

//观察数据变化
mViewModel.number.observe( this,object:Observer<Int>{
override fun onChanged(value: Int){//it:Int
binding.result. text = "$it"
}
})

//↓触发 lambda 表达式
mViewModel.number.observe( this,object:Observer<Int>{
binding.result. text = "${mViewModel.number}"
})

LiveData 与 MutableLiveData

LiveData和MutableLiveData都是Android架构组件中的一部分,用于实现数据的观察和更新。它们之间的主要区别在于MutableLiveData是LiveData的子类,因此MutableLiveData具有LiveData的所有功能,并且还可以通过setValue()和postValue()方法来更新LiveData中的数据。

具体来说,LiveData是一个具有生命周期感知能力的数据持有类,它可以感知Activity、Fragment或Service等组件的生命周期状态,并在数据发生变化时通知这些组件。而MutableLiveData是LiveData的可变版本,它允许数据的更新和修改,而LiveData只能通过setValue()方法来更新数据。

联系方面,MutableLiveData可以作为LiveData的替代品,用于在ViewModel中保存和更新数据。在ViewModel中使用MutableLiveData可以确保数据的安全性和一致性,并且能够保持数据在配置变化时的状态。LiveData和MutableLiveData都可以通过observe()方法来观察数据的变化,并在数据发生变化时通知观察者。因此,在Android开发中,通常会使用LiveData和MutableLiveData来实现数据的观察和更新,以实现数据驱动的UI更新。

面试

7.5 ViewModel的出现是为了解决什么问题? 并简要说说它的内部原理?(享学)

viewModel出现为了解决什么问题? 看下viewModel的优点就知道了:

  1. 对于activity/fragment的销毁重建,它们内部的数据也会销毁,通常可以用onSaveInstanceState()防法保存,通过 onCreate的bundle中重新获取,但是大量的数据不合适,而ViewModel会在页面销毁时自动保存并在页面加载时恢复。
  2. 对于异步获取数据,大多时候会在页面destroyed时回收资源,随着数据和资源的复杂,会造成页面中的回收操作越来越多,页面处理ui的同时还要处理资源和数据的管理。而引入ViewModel后可以把资源和数据的处理统一放在ViewModel里, 页面回收时系统也会回收ViewModel。加上databinding的支持后, 会大幅度分担ui层的负担。

内部原理: vm内部很简单,只有一个onClean方法。

vm的创建一般是这样 ViewModelProviders.of(getActivity()).get(UserModel.cla ss); 1.ViewModelProviders.of(getActivity()) 在of方法中通过传入的activity获取构造一个 HolderFragment,HolderFragment内有个 ViewModelStore,而ViewModelStore内部的一个 hashMap保存着系统构造的vm对象,HolderFragment可 以感 知到传入页面的生命周期(跟glide的做法差不多), HolderFragment构造方法中设置了 setRetainInstance(true),所以页面销毁后vm可以正常保存。 2.get(UserModel.class); 获取ViewModelStore.hashMap中的vm,第一次为空会走 创建 逻辑,如果我们没有提供vm创建的Factory,使用我们传入的activity获取application创建 AndroidViewModelFactory,内部使用反射创建我们需要 的vm 对象。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2023-2025 Annie
  • Visitors: | Views:

嘿嘿 请我吃小蛋糕吧~

支付宝
微信