EventBus也可以称为事件总线,它主要用于组件间的通信,解耦发送者与接收者(订阅者)。比如activity和service之间的通信,可能我们会采用broadcast来通信,因为这样减少了耦合,但是需要引入一个broadcast,光代码量就提升很多。而如果用EventBus只需要在service里面发送事件,activity里面接收事件即可。下面说说基本使用。
- 基本使用
先导入依赖。compile 'org.greenrobot:eventbus:3.1.1'
EventBus的发送和接收所操作都是类,所以定义一个实体类(如果只是发字符串的直接用String即可)
public class TestEvent {
String msg;
public TestEvent(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
然后需要在EventBus上注册订阅者。并且适当的时候注销订阅者。
//注册订阅者
EventBus.getDefault().register(this);
//注销订阅者
EventBus.getDefault().unregister(this);
发送事件
EventBus.getDefault().post(new TestEvent("testmessage"));
订阅事件
使用subscribe注解来定义一个方法,要求方法参数为发送者发送的事件。
@Subscribe(threadMode = ThreadMode.MAIN)
public void testMessage(TestEvent event){
hello.setText(event.getMsg());
}
在subscribe标签中可以用threaMode来指定订阅者方法体执行的线程。
ThreadMode.POSTING。默认线程,即跟发送者同一线程
ThreadMode.MAIN 主线程。
ThreadMode.MAIN_ORDERED主线程。与上面一条的区别是,指定这个线程,事件是以队列来传递的,确保发送不会阻塞
ThreadMode.BACKGROUND 后台线程(保证不是主线程),
ThreadMode.ASYNC 另开一个单独线程(保证不是主线程也不是发送者线程)
用priority来设置订阅方法的优先级,针对多个订阅方法。默认为0,优先级越高越先接收事件
sticky 用于设置粘性事件。默认为false,设置为true则为粘性事件。粘性事件就是事件一直留在缓存中,也就是我在事件发送之后在订阅也能收到事件(默认订阅必须在发送之前)。使用粘性事件的时候,发送事件要用postSticky(一般是post)要移除粘性事件可以用EventBus.getDefault().removeStickyEvent()方法来移除。
订阅者索引就不说了。给出一个我的代码,广播监听网络状态改变,并用EventBus通过activity。
public class MainActivity extends AppCompatActivity {
TextView hello;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hello= (TextView) findViewById(R.id.hello);
//注册订阅者
EventBus.getDefault().register(this);
initReceiver();
}
public void initReceiver(){
InternetReciver gr=new InternetReciver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(gr,intentFilter);
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void testMessage(TestEvent event){
hello.setText(event.getMsg());
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销订阅者
EventBus.getDefault().unregister(this);
}
}
public class InternetReciver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
Log.e("广播",action);
EventBus.getDefault().post(new TestEvent("testmessage"));
}
}
- 源码分析
首先读源码得有个入口。那么多类,那么多方法,从何处下手。个人觉得,从用法下手,怎么用就怎么读。比如EventBus,就先找到EventBus类,再找getDefau方法…依次往下看。
/**
* EventBus is a central publish/subscribe event system for Android. Events are posted ({@link #post(Object)}) to the
* bus, which delivers it to subscribers that have a matching handler method for the event type. To receive events,
* subscribers must register themselves to the bus using {@link #register(Object)}. Once registered, subscribers
* receive events until {@link #unregister(Object)} is called. Event handling methods must be annotated by
* {@link Subscribe}, must be public, return nothing (void), and have exactly one parameter
* (the event).
*
* @author Markus Junginger, greenrobot
*/
public class EventBus {
这是eventbus类的一些说明。读完后发现最后提到订阅者方法必须public,没有返回值,只有一个参数。接下来找getDefault方法。
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
这个方法其实是一个单例方法,返回一个EventBus对象。它调用了EventBus的构造方法,那我就看看EventBus的构造方法
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
...
/**
* Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a
* central bus, consider {@link #getDefault()}.
*/
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder