说到LiveData不得不提一下 Kotlin和 MVVM,为什么不得不提一下呢,有没有发现,两者只要说起其中一者就会不自觉想起另一者?
因为 MVVM 为 Kotlin 而生,MVVM有JetPack加持,LiveData为JetPack中的一枚大将。就好像狗熊岭的翠花和熊二在和光头强玩斗地主,你会问熊大去哪了。
说到LiveData,第一想到的就是:内部已经实现观察者模式,能够感知生命周期、 在组件激活的时候才会回调相应的方法,从而刷新相应的UI、不用担心内存泄漏,可以感知组件的生命周期、 当config导致Activity被重建的时候不需要手动去处理数据的存储与恢复。
既然都这么熟悉LiveData的特点了那就说一下怎么用吧
首先 lifecycle 好像已经默认支持了(androidX),所以不用去引用依赖啥的,直接就可以在你的项目中用了,不信的话直接在代码里 new 一个对象看看?如果没有的话说明不是最新版本,自己去导入一下就好了
看到LiveData源码之后,艾玛,满满登登小注释,直接提不起兴趣了,不过还好,可能某位大佬也看不下去了,所以有了 MutableLiveData, 这个好啊
任你源码在怎么迷雾,我直接把你的关键方法拿出来用,美滋滋
Kotlin中具体使用可不要被MutableLiveData中的俩个方法骗了哦
1. 声明
注意这里的类型,不仅为String,其他的也行
val ok = MutableLiveData<String>()
2.改变数据
ok.postValue("我有变化") //可在其他线程,建议使用此方法
ok.setValue("我有变化") //主线程中,能不在主线程就不在
3.改变数据后进行操作
这里会返回一个 it 参数,这个it就是改变的数据,拿到这个数据,你先干啥就干啥,一般用于 MVVM中VM逻辑层改变数据,V层获取到消息进行相应操作
ok.observe(this){
Toast.makeText(this,it,Toast.LENGTH_SHORT).show()
}
以上就是LiveData的基本使用,这篇文章是22年三月份写的,现在是23年九月份了,为什么还要来更新这篇文章呢,这一年多的时间里经历了几家公司以及不同的项目,针对LiveData的接触还是比较深的
- 拿LiveData做数据传输
- EventBus 基本去使用,导致刚接触项目的话不好去找对应的回调
首先说一下LiveData使用的话会遇到哪些问题,LiveData确实有数据变动时可以做到及时回调,去处理一些事情,但是LiveData有存储的功能,这在某些需求下确实能很好的处理问题,但是请不要通过LiveData作为一种通讯媒介,或许你可以说我在接收到LiveData回调之后可以把内容设置为 null 啊,这。。这是何苦呢,通过上面使用方式的时候也说过,这玩意可是会消耗内存,以及会影响线程进度的
这里我举一个比较深刻的实例
谷歌支付的时候,我通过LiveData作为传输媒介(此时的LiveData肯定是全局的,否则怎么去公共使用接收回调呢),回调成功或者消耗成功之后去通知外面做一些处理,比如告诉我们自己的服务端用户充值成功了,核对一下订单号,可以把我们应用内的货币给用户到账了
看似一切正常,如果用户充值成功一次,LiveData存到了数据,我们没有及时置空,或者在这一过程中出现了其他的不定因素,比如网络问题等等,不能保证会出现数据错乱的情况,以及首次进入界面的时候LiveData的回调方法如果触发了,我该怎么去拦截
此时我的建议还是使用 EventBus 去做数据通讯吧,因为他不需要你去定义全局变量,以及我们考虑线程以及内存的问题
首先说一下怎么去基本使用EventBus
- 导依赖
//EventBus
implementation 'org.greenrobot:eventbus:3.3.1'
- 使用前订阅
EventBus.getDefault().register(subscriber: Any)
- 发送消息
EventBus.getDefault().post(event: Any)
- 接收消息,方法名字随便取,主要是前面这个注解,会根据这个注解,内部找到这个方法名
@Subscribe
fun onSubscriberEvent(message: EventBusMessage) {
//做处理
}
/**
* EventBus消息体
* */
data class EventBusMessage (
var messageTag: String? = null,//消息标签
var messageBody: Any? = null //消息体
): java.io.Serializable
- 不使用了取消订阅
EventBus.getDefault().unregister(subscriber: Any)
可以看到上面订阅和发消息参数都是 Any/Object 所以在使用时只需传入对应标识符即可
只是通过 注解以及方法名去找对应的方法还是比较恶心的,除非有明确的注释,并且多个地方
订阅之后,一个地方发,其他的地方也会收到,所以在接收的消息体里面又分成 标签以及消息体,这样做的目前一方面可以让消息有指定性,我只需要在想要操作的回调里面判断一下对应的标签即可,并且把标签作为一个变量,统一存放在一个地方,我只需要找个这个标签就能找到发的地方以及收的地方,这样就不用去找注解以及分析哪个收的才是处理的了
LiveData都会用了,不去看看隔壁 Kotlin的基本使用和基类封装、MVVM和DataBinding 的使用吗?