Android面试专题系列(四):Activity之间如何进行通信→LiveDataBus
不诗意的女程序媛不是好厨师~ 转载请注明出处,From李诗雨—blog.csdn.net/cjm24848365…
现在当面试官问你:“Activity之间如何进行通信?”
其实他想听到的答案并不是:Intent , Handler,EventBus , RxBus ,广播。
上面说的这些都有些老旧和原始了,其实他想听到的是 LiveDataBus !
从18年谷歌IO大会开始 官方建议: 在Activity与Activity ,Activity与Fragment,Fragment与Fragment之间通信使用LivedataBus。
那LiveDataBus是什么呢?
它凭什么就能PK掉 Handler,EventBus , RxBus 呢?
它又有什么明显的优势呢?
别着急,我们先从一个最简单的例子说起:

【先描述一下上面的demo】
在MainActivity中有一个按钮Button,点击Button会跳转到Bactivity。
来到 Bactivity时 ,我们会收到由MainActivity发送来的消息 “面试加油!”。
并且以吐司的方式显示出来。
看完了效果,我们再来看看代码是怎么实现的吧。
【代码实现】
①在MainActivity中,当我们点击按钮时,发送一个消息:
public void click(View view) {
//发送消息
LiveDataBus.getInstance().with("msg", String.class).postValue("大家好!");
Intent intent=new Intent(this,SecActivity.class);
startActivity(intent);
}
②在Bactivity中,定义一个接收数据的观察者,并以吐司的形式显示数据。
//定义一个接收数据的观查者
LiveDataBus.getInstance().with("msg", String.class).observe(
this, new Observer<String>() {
@Override
public void onChanged(String msg) {
if(msg!=null){
Toast.makeText(SecActivity.this, msg, Toast.LENGTH_SHORT).show();
}
}
}
);
③最后我们来看看我们 极简版 的LiveDataBus.
/**
* 这条总线用于把任何类中的数据直接传递到activity或是fragment上
*/
public class LiveDataBus {
//存放订阅者
private Map<String, MutableLiveData<Object>> bus;
private static LiveDataBus liveDataBus = new LiveDataBus();
private LiveDataBus() {
bus = new HashMap<>();
}
public static LiveDataBus getInstance() {
return liveDataBus;
}
//注册订阅者,(存入map)
public synchronized <T> MutableLiveData<T> with(String key, Class<T> type) {
if (!bus.containsKey(key)) {
bus.put(key, new MutableLiveData<Object>());
}
return (MutableLiveData<T>) bus.get(key);
}
}
好了,就这么多代码,怎么样 是不是感觉很简单。
【使用说明】
发送消息时的图:


-
当我们要发送消息的时候,我们就调用
LiveDataBus.getInstance().with(
的这个api,设置一个键,设置一个value的类型(value可以为任意类型),要发送消息的时候我们就调用postValue()
,并把要发送的内容放进去。 -
发出去以后,在程序的任何其他地方(比如说是Activity或者Fragment),只要它也定义了一个观察者,并且它的键也是
“msg”
,那么这个观察者就可以收到postValue中发出的Value值。 -
我们定义的观察者中会有一个
onChanged()
回调,在onChanged()
里我们就会得到从MainActivity发送来的数据。
【分析原理】
好的,下面我们就可以来分析分析它到底是怎么实现的了。
一图解百愁,还是先给大家来画个图:

-
首先,我们设计一个LiveDataBus的总线,这个总线上面会注册很多信息。
总线上会持有一个hashMap ,以key-value的形式存放数据,key(String),value(MutableLiveData)。
并且这个总线是一个单例模式。
-
当我发送消息的时候,我们使用的api是
LiveDataBus.getInstance().with...
,当这个消息发送出去以后,它会把这个消息注册到HashMap
里面去,对应的key
就是"msg"
。 -
这个消息注册过以后,我们再来看看使用的地方:使用它的时候会去绑定一个观察者。
使用的过程中实际上使用的是同一个api即
LiveDataBus.getInstance().with...
,这个api的返回值都是一个
MutableLiveData
,所以,实际上它就把这个observe绑定到
MutableLiveData
上了。
我们来看看这个MutableLiveData
是什么吧。
MutableLiveData
继承自LiveData
:

我们进入LiveData的源码再往下看,会发现一个considerNotify()方法:

以上就是我们的具体执行流程分析了。
下面我们来做个小结~
【小结】
LiveEventBus是一款Android消息总线,基于LiveData,具有生命周期感知能力,支持Sticky,支持AndroidX,支持跨进程,支持跨APP。
关于为什么它具有生命感知能力,大家可以从源码角度来说。
即它实际上是和Glide感知生命周期一样的,内部都创建了一个空的Fragment。
LiveDataBus 与 EventBus、RxBus的 比较
-
LiveDataBus 与 EventBus 的比较:
LiveDataBus的实现及其简单,相对EventBus复杂的实现,LiveDataBus只需要一个类就可以实
-
LiveDataBus 与 RxBus 的比较:
LiveDataBus可以减小APK包的大小 并且 依赖支持也更好。因为 LiveDataBus只依赖Android官方组件LiveData,本身实现只一个类。而RxBus需要依赖RxJava和RxAndroid。
-
最后还有一点 LiveDataBus具有生命周期感知。 在Android系统中使用调用者不需要调用反注册,相比EventBus和RxBus使用更为方便,并且没有内存泄漏风险。
积累点滴,做好自己~
转载自:https://juejin.cn/post/6844904104817328136