.
EventBus是一款针对Android优化的发布-订阅事件总线。它简化了应用程序内各组件间、组件与后台线 程间的通信。其优点是开销小,代码更优雅,以及将发送者和接收者解耦。
.
Event: 事件,可以是任意类型的对象
Subscriber: 事件订阅者,在 EventBus 3.0 之前我们必须定义以onEvent开头的那几个方法,分别是
onEvent
、onEventMainThread
、onEventBackgroundThread
和onEventAsync
,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe,并且指定线程模型,默认是POSTING。Publisher: 事件发布者,可以在任意线程任意位置发送事件, 直接调用。一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可
.
EventBus3.0有四种线程模型,分别是:
POSTING(默认): 表示事件处理函数的线程跟发布事件的线程在同一个线程
MAIN: 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作
BACKGROUND: 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程
ASYNC: 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作
可以在 处理事件 的时候来设置线程模型,如下所示:
//设置线程模型
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXXX(MessageEvent message) {
//消息的内容
Log.d("接收的信息内容:",message);
}
.
.
引入依赖
在使用之前先要在build.gradle
引入如下依赖:
dependencies{
implementation 'org.greenrobot:eventbus:3.1.1'
}
.
EventBus使用起来分为以下5个步骤:
.
1. 自定义一个事件类
作用: 在程序内部就使用该对象作为通信的信息
public class MessageEvent {
public final String message;
private MessageEvent(String message) {
this.message = message;
}
public static MessageEvent getInstance(String message) {
return new MessageWrap(message);
}
}
2. 在需要订阅事件的地方注册事件
在MainActivity中注册事件,如下所示:
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_,ain);
initData();
}
public vaid init(){
//注册事件
EventBus.getDefault().register(this);
}
}
3. 发送事件
创建了SecondActivity来发布消息,代码如下所示:
public class SecondActivity extends AppCompatActivity{
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_,ain);
sendMessag();
}
public vaid sendMessag(){
//发送消息
EventBus.getDefault().post(new MessageEvent("你好!我是萝莉"));
}
}
4. 在事件接收方处理事件
在MainActivity中接收事件并进行修改的处理,如下所示:
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_,ain);
initData();
}
public vaid init(){
//注册事件
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void GetMessage(MessageEvent message) {
//打印消息的内容
Log.d("接收的信息内容:",message);
}
}
5. 取消事件订阅
在MainActivity的 onDestroy()
方法中取消订阅事件,如下所示:
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_,ain);
initData();
}
public vaid init(){
//注册事件
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void GetMessage(MessageEvent message) {
//打印消息的内容
Log.d("接收的信息内容:",message);
}
@Override
protected void onDestroy(){
super.onDestroy();
//取消注册事件
EventBus.getDefault().unregister(this);
}
}
6. 添加 ProGuard 混淆规则
在 proguard-rules.pro
文件添加混淆规则
#eventbus打包混淆
- keepattributes *Annoation*
- keepclassmembers class **{
@org.greenrobot.eventbus.Subscrile<methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode{ *; }
# Only requirend if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.
ThrowableFailurEvent{
<init>(java.lang.Throwable);
}
.
.
EventBus还支持发送黏性事件,就是在发送事件之后再订阅该事件也能收 到该事件,这跟黏性广播类似。
.
为了验证黏性事件,我们修改以前的代码,如下所示
1. 订阅者处理黏性事件
在MainActivity中新写一个方法用来处理黏性事件
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void GetViscosityMessage(MessageEvent message) {
//打印消息的内容
Log.d("接收的黏性信息内容:",message);
}
2. 发送黏性事件
在SecondActivity发送黏性事件
public vaid sendMessag(){
//发送消息
EventBus.getDefault().postSkticky(new MessageEvent("你好!我是萝莉"));
}
.
.
在 Subscribe注解
中总共有3个参数,其中 priority
参数用来指定订阅方法的优先级,是一个整数类型的值,默认是0,值越大表示优先级越大。在某个事件被发布出来的时候,优先级较高的订阅方法会首先接受到事件。
使用:
@Subscribe(threadMode = ThreadMode.POSTING, priority = 0)
注意:
只有当两个订阅方法使用相同的ThreadMode参数的时候,它们的优先级才会与priority指定的值一致
只有当某个订阅方法的ThreadMode参数为POSTING的时候,它才能停止该事件的继续分发
具体使用:
public class MainActivity extends AppCompatActivity{
// 用来判断是否需要停止事件的继续分发
private boolean stopDelivery = false;
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_,ain);
initData();
}
public vaid init(){
//注册事件
EventBus.getDefault().register(this);
}
/*-------------------- 对事件进行处理 --------------------*/
@Subscribe(threadMode = ThreadMode.POSTING, priority = 0)
public void onGetMessage(MessageEvent message) {
//打印消息的内容
Log.d("接收的信息内容:",message);
}
// 订阅方法,需要与上面的方法的threadMode一致,并且优先级略高
@Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)
public void onGetStickyEvent(MessageWrap message) {
//打印消息的内容
Log.d("接收的信息内容:",message);
if (stopDelivery) {
// 终止事件的继续分发
EventBus.getDefault().cancelEventDelivery(message);
}
}
@Override
protected void onDestroy(){
super.onDestroy();
//取消注册事件
EventBus.getDefault().unregister(this);
}
}
.
.
如果你的项目中已经引入RxJava ,那么可以用 RxJava 来实现事件总线 RxBus,以替代EventBus和 otto。
引入依赖
在使用之前先要在build.gradle
引入如下依赖:
dependencies{
implementation 'io.reactivex:rxjava:1.2.0'
implementation 'io.reactivex:rxandroid:1.2.1'
}
1. 创建RxBus
首先创建RxBus。这里的RxBus只是支持基本的功能,读者如果想要添加一些功能,则可以自定义添加,代码如下所示:
public class RxBus{
private static volatile RxBus rxBus;
private final Subject<Object,Object> subject = new SerializedSubject<>(PublishSubject.create);
//使用单例模式的双重检查模式
public static RxBus getInstance(){
if(rxBus == null){
synchronized(RxBus.class){
if(rxBus == null){
rxBus = new RxBus();
}
}
}
return rxBus;
}
public void post(Object ob){
subject.onNext(ob);
}
public <T> Observable<T> toObservable(Class<T> eventType){
//ofType方法中包含了filter和cast的操作。
//通过filter操作符来判定是否是指定的类型,如果不是就不提交 给订阅者。
//cast操作符则用来将Observable转换成指定类型的Observable
return subject.ofType(eventType);
}
}
2. 发送事件
在MainActivity 中发送事件
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
public vaid init(){
//发送事情
RxBus.getInstance().post(new MessageEvent("用RxJava实现RxBus"));
}
}
3. 接收事件
在TwoActivity中接收事件,如下所示:
public class TwoActivity extends AppCompatActivity{
private Subscriber subscription;
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
initData();
}
public vaid init(){
//接收消息
subscription = RxBus.getInstance.toObservable(MessageEvent.class).subscribe(new Action1<MessageEvent>(){
@Override
public void call(MessageEvent messageEvent){
Log.v("MainActivity发送过来的消息:",messageEvent.getMessage());
}
}
}
@Override
protected void onDestroy(){
super.onDestroy();
//取消订阅事件
if(subscription != null && !subscription.isUnsubscribed()){
subscription.unsubscribe();
}
}
}