目录
- 前言
- 一、BroadcastReceiver 广播
- 二、EventBus
- 三、RxBus
- 四、LiveDataBus
- 五、FlowBus
- 总结
前言
消息总线又叫事件总线,为什么我们需要一个消息总线呢?是因为随着项目变大,页面变多,我们可能出现跨页面、跨组件、跨线程、跨进程传递消息与数据,为了更方便的直接通知到指定的页面实现具体的逻辑,我们需要消息总线来实现。
从最基本的 BroadcastReceiver 到 EventBus 再到RxBus ,后来官方出了AndroidX jetpack 我们开始使用LiveDataBus,最后到Kotlin的流行出来了FlowBus。我们看看他们是怎么一步一步演变的。
一、BroadcastReceiver 广播
我们再初入 Android 的时候都应该学过广播接收者,分为静态广播和动态注册广播,在高版本的 Android 中限制了我们一些静态广播的使用,不过我们还是能通过动态注册的方式获取一些系统的状态改变。像常用的电量变化、网络状态变化、短信发送接收的状态等等。
比如网络变化的监听:
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
application.getApplicationContext().registerReceiver(InstanceHolder.INSTANCE, intentFilter);
在消息中线中,我们可以使用本地广播来实现 LocalBroadcastManager 消息的通知。
LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(mContext);
BroadcastReceiver mLoginReceiver = new LoginSuccessReceiver();
mLocalBroadcastManager.registerReceiver(mLoginReceiver, new IntentFilter(Constants.ACTION_LOGIN_SUCCESS));
private class LoginSuccessReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//刷新Home界面
refreshHomePage();
//刷新未读信息
requestUnreadNum();
}
}
//记得要解绑对应的接收器
mLocalBroadcastManager.unregisterReceiver(mLoginReceiver);
这样就可以实现一个消息通知了。相比 EventBus 它的性能和空间的消耗都是较大的,并且只能固定在主线程运行。
二、EventBus
EventBus最大的特点就是简洁、解耦,可以直接传递我们自定义的消息Message。EventBus简化了应用程序内各组件间、组件与后台线程间的通信。记得2015年左右是非常火爆的。
EventBus的调度灵活,不依赖于 Context,使用时无需像广播一样关注 Context 的注入与传递。可继承、优先级、粘滞,是 EventBus 比之于广播的优势。几乎可以满足我们全部的需求。
最初的EventBus其实就是一个方法的集合与查找,核心是通过register方法把带有@Subscrib注解的方法和参数之类的东西全部放入一个List集合,然后通过post方法去这个list循环查找到符合条件的方法去执行。
如何使用EventBus,一共分5步:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus);
EventBus.getDefault().register(MainActivity.this); //1.注册广播
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(MainActivity.this); //2.解注册广播
}
/**
* 3.传递什么类型的。定义一个消息类
*/
public class MessageEvent {
public String name;
public MessageEvent(String name) {
this.name = name;
}
}
@OnClick({R.id.bt_eventbus_send_main, R.id.bt_eventbus_send_sticky})
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_eventbus_send_main:
//4.发送消息
EventBus.getDefault().post(new MessageEvent("我是主页面发送过来的消息"));
finish();
break;
}
}
/**
* 5.接受到消息。需要注解
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN) //主线程执行
public void MessageEventBus(MessageEvent event) {
//5。显示接受到的消息
mTvEventbusResult.setText(event.name);
}
EventBus的性能开销其实不大,EventBus2.4.0 版是利用反射来实现的,后来改成 APT 实现之后会好很多。主要问题是需要定义很多的消息对象,消息太多之后就感觉管理起来很麻烦。当消息太多之后容器内部的查找会出现性能瓶颈。
就算如此 EventBus 也是值得大家使用的。
三、RxBus
RxBus是基于RxJava实现的,强大是强大,但是学习成本比较高,需要额外导入RxJava RxAndroid等库,这些库体积还是较大的。可以实现异步的消息等。
本身的实现是很简单的:
public class RxBus {
private volatile static RxBus mDefaultInstance;
private final Subject