• 四月
  • 18
  • load

android viewmodel的使用 2021-04-18 21:58:31

上次发布的databinding基本使用方法时提到了ViewModel,但仅仅是简单介绍并略过,并说明了找个时间介绍一下,因此,这里重新再开一篇文章单独介绍ViewModel是如何使用的(其实ViewModel没什么难度,但自己挖的坑,跪着也要填掉)。

那么,在mvvm里,ViewModel也能做到model的工作,但比model麻烦一点,那么,ViewModel到底有什么特点呢?

ViewModel,它是介于view和model之间的东西,就像mvp的persenter,mvc的controller,因此,它是可以替activity实现一些工作的。比起persenter和controller,ViewModel分离更加彻底。

那彻底到什么程度?它不持有view引用即可完成view的业务逻辑,因此,就算你旋转屏幕导致重新跑了一次生命周期,也不会影响到ViewModel。

有同学产生疑问了,我直接利用onSaveInstanceState保存和恢复数据不也可以?没错,确实可以,但只适合存放一些可被序列化和反序列化的数据,一旦遇到像List<Bitmap>这样的东西就蛋疼了。而ViewModel就没有这种痛点。

 

ViewModel的生命周期:

它贯穿了整个activity的生命周期,当activity销毁后(回调了onDestroy),ViewModel会回调onCleared

 

如何使用?

1.依赖:

一般情况下,你不需要引入什么依赖,这东西一般是天然自带的,哪怕你没启动databinding,也是自带的。

虽说是自带,但一般不是最新的,如果介意的话可以手动引入(https://developer.android.google.cn/jetpack/androidx/releases/lifecycle)

也许有位同学开始想了,lifecycle又是什么玩意?其实就是一个感知生命周期的组件,而ViewModel就是其中之一,也就是说,我们讨论的ViewModel,其实只是lifecycle的组件之一。

 

2.继承ViewModel或AndroidViewModel

上代码前先说明,ViewModel和AndroidViewModel有什么区别?

它们之间只有一个区别,AndroidViewModel会提供application,而ViewModel什么都不给你,AndroidViewModel是继承ViewModel实现出来的类,因此AndroidViewModel其实就是ViewModel。

 

ViewModel:

 

activity:

 

layout:

 

可见,业务层已经交给了ViewModel实现了,我们的activity只关心界面怎么刷新,彻底分离了业务和界面。

 

关于共享数据:

如果你的activity中,有多个Fragment且需要互相通信,可能需要A fragment等待B fragment初始化,又或者反回来等待,还要创建接口这类调用,activity无疑,变成了中介者,通信量高还会让activity躺着也变臃肿。总之就是非常麻烦。

ViewModel则很好地解决这个痛点,这里可以参考官方的例子

 

看到这里,相信大家仿佛看见羊驼在奔腾。

逻辑是分离得够彻底了,但如果我界面几百个view,岂不是要创建几百个观察者?

这里,就需要databinding协助了,databinding使用方法可以查看上一篇文章(http://www.sqsxblog.com/article/24.html)

然后吧,使用方法变成这样了

activity

 

layout:

 

viewmodel不变

 

在databinding的加持下,渲染工作完全交给了layout,除非有什么特殊逻辑,不然你根本不需要创建什么观察者。要做的不过是确定lifecycle连接到activity即可

 

至于viewmodel的注意事项也要说下

1.绝对不要让viewmodel持有activity,lifecycle,activity的context引用,viewmodel的生命周期必然比activity长,只有activity销毁完成后viewmodel才会销毁,如果让viewmodel持有引用,没有合理处理会导致activity没有回收,导致内存泄漏。

2.因为没有activity引用,所以你真正意义上只能干业务,跟界面沾边的没法处理,例如你想跳转一个新的activity,显示一个dialog,很遗憾,你得在view层写观察者才能实现。

3.可以利用viewmodel跨fragmnet通信,前提这两个fragment是建立在同一个activity上;activity和activity不能共享同一个viewmodel。

 

viewmodel就这样,没什么难的(如果要剖析源码,我觉得需要重新评估难度)。

 

原创文章,转载请注明出处

正在加载评论...

0 / 240

警告

确定