一、EventBus 简介
EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,Gihub地址是:EventBus。它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。
二、EventBus使用场景
应用程序内各组件间、组件与后台线程间的通信。
比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。
三、EventBus使用
1.添加依赖
Android studio的module的build.gradle中配置编译库连接:目前最新的版本为3.1.1
compile 'org.greenrobot:eventbus:3.1.1'
2.事件的定义
public static class MessageEvent {
}
3.事件订阅者的准备
声明并且采用注解的方式来定义订阅者的方法,默认的情况下,注解方法中的threadMode为MAIN,表示在主线程中运行,事件处理的函数名可以自行定义。下面会讲述4中线程的模式。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
};
4.事件的发布者的准备
事件发布者的工作相对比较简单,最常用的是采用post或者postSticky的方法,将new出来的事件对象发布出来,这两种发布的方法,将会在下面知识讨论中进行讲述其区别。
EventBus.getDefault().post(new MessageEvent());
5.注册与注销EventBus
那么问题来了,时间的订阅者如何才能得知有事件被发布了呢?因此在使用EventBus3.0的时候需要在事件订阅的那个activity或者fragment中进行注册,
其注册代码的地方依附于activity或者fragment的生命周期,即:
@Override
public void onStart() {
super.onStart();
//在事件被订阅的界面中注册EventBus
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
//注销EventBus
EventBus.getDefault().unregister(this);
}
6.EventBus3.0粘性事件
除了上面讲的普通事件外,EventBus还支持发送黏性事件,就是在发送事件之后再订阅该事件也能收到该事件,跟黏性广播类似。
为了验证粘性事件我们修改以前的代码:
1)订阅粘性事件
在MainActivity中我们将注册事件添加到button的点击事件中:
bt_subscription.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//注册事件
EventBus.getDefault().register(MainActivity.this);
}
});
2)订阅者处理粘性事件
在MainActivity中新写一个方法用来处理粘性事件:
@Subscribe(sticky = true)
public void ononMoonStickyEvent(MessageEvent messageEvent){
tv_message.setText(messageEvent.getMessage());
}
3)发送黏性事件
在SecondActivity中我们定义一个Button来发送粘性事件:
bt_subscription.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new MessageEvent("粘性事件"));
finish();
}
});
好了运行代码再来看看效果,首先我们在MainActivity中并没有订阅事件,而是直接跳到SecondActivity中点击发送粘性事件按钮,
这时界面回到MainActivity,我们看到TextView仍旧显示着MainActivity的字段,这是因为我们现在还没有订阅事件。
总结:粘性事件就是先发送这个事件,在需要接收的时候进行订阅接收
普通事件就是必须先进行订阅才能够进行接收
在接收事件的Activity或者Fragment中进行注册与解注册
一个fragment给另一个还没有初始化的fragment发送消息得使用黏性事件进行发送
7.EventBus的四种线程模型---ThreadMode
1)ThreadMode: POSTING
默认的线程模式,如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,
也就是说发布事件和接收事件在同一个线程。此外,在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
2)ThreadMode: MAIN
事件的处理会在UI线程中执行。此外也不能在处理事件中执行比较耗时的操作,否则也会引起ANR。
3)ThreadMode: BACKGROUND
如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
4)ThreadMode: ASYNC
无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作,因为这牵涉到UI的更新只能在 main thread中更新。
8注意事项
在一个fragment中发消息给一个还没有初始化的fragment必须发送粘性事件,因为这个事件还没有在那个初始化的fragment中注册,因此只能使用粘性事件发送
网友评论