由于EventBus 3.0 和之前的版别差异较大,下面介绍的内容是基于EventBus3.0 。EventBus,是一个基于Publish/Subscribe的事情总线结构, 这儿不做过多具体介绍。
下面是EventBus工程和文档地址:
GitHub : github.com/greenrobot/…
官方文档:greenrobot.org/eventbus/do…
装备
这儿介绍一下装备。
-
根本装备:
在app 工程下的build.gradle
中增加依靠:dependencies { ...... // 省掉部分依靠 implementation 'org.greenrobot:eventbus:3.1.1' }
-
假如运用索引(index)在app 工程下的
build.gradle
中增加依靠:android { defaultConfig { .... // javaCompileOptions { annotationProcessorOptions { arguments = [ eventBusIndex : 'com.cfox.eventbusdemo.index.EventBusIndex' ] } } } } dependencies { implementation 'org.greenrobot:eventbus:3.1.1' annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1' }
快速运用
-
创立音讯类
这个类能够任意定义, 作为传输运用public class MessageObjectOne { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }
-
注册
注册运用EventBus实例register(Object subscriber)
办法进行注册。@Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); }
-
刊出
刊出运用EventBus实例unregister(Object subscriber)
办法进行注册。@Override protected void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
-
订阅接事情
订阅接纳办法运用注解@Subscribe
@Subscribe(threadMode = ThreadMode.MAIN, priority = 2, sticky = true) public void subMessageOne(MessageObjectOne msgOne) { Log.d(TAG, "subMessageOne: " + msgOne.getInfo()); }
上面代码发现,注解
@Subscribe
有三个参数,还有不同的值。下面会介绍 -
发布音讯
MessageObjectOne object = new MessageObjectOne(); object.setInfo("hello world"); EventBus.getDefault().post(object);
@Subscribe参数
threadMode
ThreadMode.POSTING(默认):假如运用事情处理函数指定了线程模型为POSTING,那么该事情在哪个线程发布出来的,事情处理函数就会在这个线程中运转,也便是说发布事情和接纳事情在同一个线程。在线程模型为POSTING的事情处理函数中尽量防止履行耗时操作,由于它会阻塞事情的传递,甚至有可能会引起ANR.
ThreadMode.MAIN:
事情的处理会在UI线程中履行。事情处理时间不能太长,长了会ANR的。ThreadMode.BACKGROUND:假如事情是在UI线程中发布出来的,那么该事情处理函数就会在新的线程中运转,假如事情原本便是子线程中发布出来的,那么该事情处理函数直接在发布事情的线程中履行。在此事情处理函数中禁止进行UI更新操作。
ThreadMode.ASYNC:无论事情在哪个线程发布,该事情处理函数都会在新建的子线程中履行,同样,此事情处理函数中禁止进行UI更新操作。
priority
订阅办法的优先级影响订阅办法的履行次序。优先级越高越被先履行。
sticky
假如设置为true
则该订阅事情为粘性事情(后面会具体介绍)。
运用索引(index)
在EventBus中运用索引能够进步app功率。运用索引的装备上面已经介绍了,下面介绍一下:
arguments = [ eventBusIndex : 'com.cfox.eventbusdemo.index.EventBusIndex' ]
上面这句是装备生成索引的目录(com.cfox.eventbusdemo.index
)和索引类的类名(EventBusIndex
), 装备好索引后,重新build
一下工程就会生成索引类。
索引为什么能进步app的功率,假如没有运用索引,在注册的时分会经过反射获取类中订阅的事情,运用索引后注册时在索引中查询订阅事情,所以功率会进步很多。
-
增加运用索引
装备好索引后,还要将生成的索引增加的项目中,不然索引是不会收效的。索引建议在运用的Application
中增加,如下:public class App extends Application { @Override public void onCreate() { super.onCreate(); EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus(); } }
假如在项目中运用EventBus.getDefault()
办法运用EventBus,在运用索引的时分一定要运用installDefaultEventBus()
办法增加索引。
有的文章中运用build()
办法增加索引,如下办法:
public class App extends Application {
private EventBus mEventBus;
@Override
public void onCreate() {
super.onCreate();
mEventBus = EventBus.builder().addIndex(new EventBusIndex()).build();
}
public EventBus getEventBus() {
return mEventBus;
}
}
注意:假如运用这种办法增加索引一定要运用build()
回来的EventBus实例, 假如运用EventBus.getDefault()
办法运用EventBus,索引将不会收效。
stick 事情
-
stick 事情?
stick 事情便是假如某个目标的stick 事情被发布后,该目标的stick订阅事情没有注册到EvnetBus上,当该目标的stick订阅事情注册到EventBus上时, 该目标的订阅事情将当即被履行。 -
怎么订阅stick 事情
在订阅事情时将sticky
设置为true
(sticky = true
)@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void subMessageOne(MessageObjectOne msgOne) { Log.d(TAG, "subMessageOne: " + msgOne.getInfo()); }
-
发布stick 事情
MessageObjectOne object = new MessageObjectOne(); object.setInfo("hello world"); EventBus.getDefault().postSticky(object);
深化一点
上面介绍了比较简单的是运用,EventBus 运用是比较灵敏的,下面以运用节点进一步解说。
-
注册
官方文档中的示例如下:@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); }
重官方给出的示例中是在
onStart
和onStop
中进行注册和刊出, 其实这仅仅其间的一个运用场景, 不必纠结在什么地方注册和刊出,了解原理依据需求灵敏运用。注册的是什么?
从注册办法中能够看到register
办法中传入的是一个目标。经过检查源码知道,注册时经过反射获取到订阅的事情(假如运用索引,从索引类中获取),也便是说,任何目标只要目标中订阅了事情,就会把订阅的事情注册到EventBus中。如下示例:将一个一般目标注册到EventBus 中
public class EventHandler { private static final String TAG = "EventHandler"; @Subscribe public void text(MessageObject object) { Log.d(TAG, "text: " + object.getInfo()); } } EventHandler mHandler = new EventHandler(); EventBus.getDefault().register(mHandler); // 注册 EventBus.getDefault().unregister(mHandler); // 刊出
注册后,假如发布这个类型的音讯,这个类中订阅的事情就会呼应。不用的时分刊出一下就能够了。
-
订阅事情
在EventBus3.0中订阅事情运用注解@Subscribe
,所以能够随意命名。事情参数必须只要一个参数。不同音讯的订阅
EventBus是依据事情音讯参数的类型进行分发相呼应的,也便是说,post一种类型的音讯,只要订阅相同音讯的订阅事情才能呼应。如下订阅事情代码示例:@Subscribe(threadMode = ThreadMode.MAIN) public void subMessageOne(MessageObjectOne msgOne) { Log.d(TAG, "subMessageOne: " + msgOne.getInfo()); } @Subscribe(threadMode = ThreadMode.MAIN) public void subMessageTwo(MessageObjectTwo msgTwo) { Log.d(TAG, "subMessageTwo: " + msgTwo.getInfo()); }
运用下面办法发送音讯将只要
subMessageOne
订阅事情得到呼应MessageObjectOne object = new MessageObjectOne(); object.setInfo("hello world"); EventBus.getDefault().post(object);