1.使用
1.定义一个evnet;
public static class MessageEvent
2.准备观察者
声明和注释你的订阅方法,可选地指定线程模式
@Subscribe(threadMode = ThreadMode.MAIN) //比如这个就指定主线程
public void onMessageEvent(MessageEvent event) {/* Do something */};
关于类型的解释介绍请查阅https://www.jianshu.com/p/a448a161674a
注册和反注册在你的使用中,例如在activity中
@Override
public void onCreate() {
super.onCreate();
EventBus.getDefault().register(this);
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
3.post你的事件event
EventBus.getDefault().post(new MessageEvent());
4.订阅者接收事件并处理
onEvent(使用onEvent来接收事件,那么接收事件和post事件在同一个线程中执行)
onEventMainThread( 使用onEventMainThread来接收事件,那么不论post事件在哪个线程运行,接收事件永远在UI线程执行)
onEventBackgroundThread(使用onEventBackgroundThread来接收事件,如果post事件在子线程运行,那么接收事件直接在同一个线程
运行,如果post事件在UI线程,那么会启动一个子线程接收事件)
onEventAsync(使用onEventAsync接收事件,无论post事件在哪个线程 (UI或者子线程) 执行,接收事件都会在一个新的子线程执行)
2.源码分析
1.首先看下他的
EventBus.getDefault()
这里看到,他是用到了单例,保证eventbus对象的唯一,在看看他的构造函数
这里面new了几个hashmap,用来存储订阅者的信息,还有几个poster,用来在不同的线程中post事件的。
mainThreadPoster对应的主线程接收事件
backgroundPoster 某个子线程
asyncPoster 也是对应的某个子线程
2.看他的register
一个管理获取,查询订阅者和订阅者method 的对象subscriberMethodFinder,之后通过反射拿到订阅者的修饰符,方法参数等信息,判断了订阅者的方法参数只能是一个参数,并且是public修饰的,不能是static,final修饰的,否则的话抛出异常
获取的
method,反射方法的对象,Threadmode:线程模式对象,eventType事件的类型
取出method 中的eventtype,然后创建一个Subscription对象,用于存放method和订阅者信息的,之后将eventtype和Subscriptions关联起来,之后把Subscription加入到Subscriptions中,为什么Subscriptions和eventtype关联,因为每个订阅者的可能是不同的eventtype类型,
3.在看下post
currentPostingThreadState这个方法获取当前线程的状态,是否是post,是否是主线程等
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
之后判断队列里是否有信息,不为空的话就获取post
4.在看下unregister
通过订阅者拿到所有的定义subscribedTypes,之后遍历subscribedTypes,拿到eventtype
之后通过eventtype,获取到订阅者集合,拿到他的size,进行遍历,找到这个订阅者,是他的active是false,并且移除。