阅读 491

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()方法:

在这里插入图片描述
这就是一个通知,通过我们的通知 去通知我们的观察者 执行onChanged()。

以上就是我们的具体执行流程分析了。

下面我们来做个小结~

【小结】

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使用更为方便,并且没有内存泄漏风险。

积累点滴,做好自己~