ViewModel探索(1)

本文探讨了Android Jetpack的ViewModel组件,解释了它的作用和特性,如数据存储和跨页面共享。详细介绍了如何声明和获取ViewModel,以及ViewModel如何在配置变化时保持数据。还探讨了ViewModel的创建和存储过程,包括ViewModelProvider、Factory和ViewModelStore的角色。最后,文章提到了ViewModel在Activity重建时的数据恢复机制。
摘要由CSDN通过智能技术生成

首先希望这篇文章如果对大家有帮助的话,可以点一个善意的赞或者收藏,这对我创作来说非常重要!先感谢大家啦~

1.ViewModel是什么?

官方解释: ViewModel是Jetpack组件里面一个具备宿主生命感知能力的数据存储组件;

从官方的解释可以看出有两点:

  1. 数据存储组件
  2. 具备宿主感知能力

从第一点来看,我首先有第一个疑问,数据存储组件?这有什么特别的,我为何不新建一个类保存数据,非要放到ViewModel呢?然后第二点乍一眼看,我盲猜ViewModel只是集成了LifeCycle的能力,然后才拥有的宿主感知能力吧?

接下来我们简单的解释一下以上的疑问吧~!

首先ViewModel他的作用确实是用于保存页面(甚至是应用维度)的数据,其次就是ViewModel拥有数据还原的能力,我们都知道一旦配置发生变化(页面旋转、分辨率调整、系统字体变更),Activity就会进行重建,在重建后如果我们的数据是定义在Activity上,那这个时候数据就会丢失,但是如果我们是放在ViewModel上,页面重建后我们拿到的ViewModel实体依旧是重建前的实体,那就意味着原本我们保存在ViewModel里面的数据也会得以保存。

但是这个时候就会有人有疑问,这只是重建啊,那么如果发生了因内存不足或者电量不足下的Activity回收,那回显时ViewModel也会恢复保存数据吗?

答案是会的,但是依赖SavedState这个组件,我们使用ViewModel + SaveState之后我们就能应对到这种情况!

而且使用ViewModel还有一个好处,就是充当MVVM里面VM的角色,让Activity的代码更加清爽,只专注View层相关的事务即可!如果有小伙伴不了解MVVM的话,可以去搜索一下相关资料,在这里就不展开说了!

至于宿主感知能力,我们就在原理章节顺路解开!话不多说我们先看看ViewModel是怎么使用的!

2.ViewModel怎么用?

既然是数据存储组件,我们关注的有以下几点:

  1. 怎么声明ViewModel?
  2. 怎么在Activity或Fragment中获取ViewModel?

2.1 声明ViewModel

//继承ViewModel
class MyViewModel: ViewModel(){
   
    //在ViewModel下声明自己的数据
    val data=MutableLiveData<String>()
    
    //声明处理数据逻辑等函数
    fun loadData():MutableLiveData<String> {
   
        if (data.value == null) {
   
            data.setValue(fetchDataFormRemote())
        }
        return data
    }

    fun fetchDataFormRemote():String{
   
        return  "从服务器获取的数据";
    }
}

2.2 获得声明的ViewModel对象

class MainActivity : ComponentActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        //通过ViewModelProvider获得我们上面声明的MyViewModel对象
        val myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
        //调用加载数据方法,并打印
        print(myViewModel.loadData())
  
    }
}

以上就是ViewModel + Activity最常用的使用方式了,可以说是很简单了~

2.3 其他使用场景

2.3.1 跨页面数据共享

比如我们有时候想保存一些全局数据,这时候很多页面都要获取该数据,那么除了声明静态数据之外,我们也可以通过以下方式保存全局数据:

//Application继承ViewModelStoreOwner接口,实现ViewModelStore能力
class MyApp : Application(), ViewModelStoreOwner {
   

    private val viewModelStore: ViewModelStore by lazy {
   
        ViewModelStore()
    }

    override fun getViewModelStore(): ViewModelStore {
   
        return viewModelStore
    }
    
}

class MainActivity : ComponentActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        //与页面不同的是,我们通过application获取MyViewModel,此时ViewModel是保存在Application中
        val myViewModel = ViewModelProvider(application).get(MyViewModel::class.java)
        myViewModel.loadData()
        print(myViewModel.data.value)
    }
}

2.3.2 配合SavedState使用
//在构造函数中声明SavedStateHandle
class MyViewModel(val savedStateHandle: SavedStateHandle) : ViewModel() {
   
    private val DATA_SAVE_KEY = "save_key";

    val data = MutableLiveData<String>()

    fun loadData(): MutableLiveData<String> {
   
        if (data.value == null) {
   
            //1.首先先从内存中尝试还原数据
            val
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值