1. 引入EventBus
implementation 'org.greenrobot:eventbus:3.1.1'
2. 注册和注销EventBus
//注册位置:onCreate 或者 onStart
EventBus.getDefault().register(object);
//不使用的时候记得unregister onDestroy 或者 onStop
EventBus.getDefault().unregister(object);
3. 订阅或者发布事件
//注册的object内部实现
//func 函数名称,用户自己定义
//T event ,T 表示某个类型事件,T可以是基本类型,也可以是class,不同的类表示不同的事件(注意继承关系)
//threadMode 不同,响应行为不一样,后面解释
@Subscribe(threadMode = ThreadMode.MAIN)
public void func(T event ){};
//发布事件,一般使用Post,稍后讲解postSticky
//调用post方法的时候,如果订阅者和post在同一线程则post将等所有消费者完成之后返回。
//如果不在同一线程则将事件投递到pendingqueue的队列
//(mainThreadPoster,backgroundPoster,asyncPoster)里面去之后再去触发事件。
EventBus.getDefault().post(T event);
//事件订阅者在事件发布之后注册的也能接收到该事件的特殊类型,订阅者必须指定sticky = true
//只保留最后一个sticky事件
//@Subscribe(sticky = true,threadMode = ThreadMode.MAIN_ORDERED)
//public void func(T event ){};
EventBus.getDefault().postSticky(T event);
4. ThreadMode 的五种模式
- ThreadMode.MAIN
 
- 订阅者方法将在主线程(UI线程)中被调用
 - 如果发布事件的线程是主线程,那么该模式的订阅者方法将被直接调用否则进入队列
 - 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程(如果主线程是Poster)
 
- ThreadMode.MAIN_ORDERED
 
- 订阅者方法将在主线程(UI线程)中被调用
 - 事件将先进入队列然后才发送给订阅者,所以发布事件的调用将立即返回
 - 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程(如果主线程是Poster)
 - 不同的线程发送消息,先加入队列的会优先执行
 
- ThreadMode.BACKGROUND
 
- 每一个订阅者方法将在后台同一个线程中被调用
 - 如果发布事件的线程不是主线程,那么订阅者方法将直接在该线程中被调用
 - 如果发布事件的线程是主线程,那么将使用一个单独的后台线程,该线程将按顺序发送所有的事件
 
- ThreadMode.POSTING
 
- 默认的线程模式
 - 订阅者将在发布者的线程中被调用(同步的,只有所有订阅者处理完成之后post才返回)
 
- ThreadMode.ASYNC
 
- 保证每个订阅者方法将在一个独立的子线程中被调用
 - 发布事件的调用将立即返回
 - 避免触发大量的长时间运行的订阅者方法,以限制并发线程的数量
 - EventBus使用了一个线程池来有效地重用已经完成调用订阅者方法的线程。
 
配合下面部分post调度源码将更加清楚(invokeSubscriber直接在当前线程调用)。
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
            case POSTING:
                invokeSubscriber(subscription, event);
                break;
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);
                } else {
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
            case MAIN_ORDERED:
                if (mainThreadPoster != null) {
                    mainThreadPoster.enqueue(subscription, event);
                } else {
                    // temporary: technically not correct as poster not decoupled from subscriber
                    invokeSubscriber(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }5. 多继承的子类订阅事件分析(以String为例)
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
....
}
EventBsu.java
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    //获取Event的Class
        Class<?> eventClass = event.getClass();
        boolean subscriptionFound = false;
        if (eventInheritance) {
          //获取Event的所有父类
            List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
            int countTypes = eventTypes.size();
            //投递所有父类Event
            for (int h = 0; h < countTypes; h++) {
                Class<?> clazz = eventTypes.get(h);
                subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
            }
        } else {
        }
       ...
       }此时注意eventTypes 的size和值

所以如果我们订阅了以上五种class,那么 EventBus.getDefault().post(String);将被以上订阅者接受。至于接受顺序和ThreadMode相关。eg:ThreadMode.MAIN_ORDERED,那么订阅者顺序则为String->Serializable->Comparable->CharSequence->Object即:Sting的继承顺序。

@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(String event) {
Log.i("", "Subscribe Recv String Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(Serializable event) {
Log.i("", "Subscribe Recv Serializable Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(Comparable event) {
Log.i("", "Subscribe Recv Comparable Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(CharSequence event) {
Log.i("", "Subscribe Recv CharSequence Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(Object event) {
Log.i("", "Subscribe Recv Object Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}
6. ASYNC 模式保证每个订阅者都是独立的线程和是否多继承没关系

6. BACKGROUND 每一个订阅者方法将在后台同一个线程中被调用


7. 订阅者不同类型情景
 1.进入队列顺序:多继承:子类->父类继承顺序。eg:String->Serializable->Comparable->CharSequence->Object 2.进入队列情况,根据不同订阅类型来决定。
 3.执行顺序根据线程的cpu调度决定。
eg:以在UI线程Post(String)t为例,分析下列事件调用线程和执行顺序情况。
//进入UI线程队列
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(String event) {}
//不进入队列,直接执行,所以会优先于事件String 执行
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMainModeEvent(Serializable event) {}
//不进入队列,直接执行,由于Comparable 顺序在Serializable 后面,所以会优先
//事件String 执行d但是在事件Serializable 之后执行,该事件执行完成之后Post返回。
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMainModeEvent(Comparable event) {}
//进入后台线程,执行顺序由cpu调度决定
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMainModeEvent(CharSequence event) {}
//进入后台线程,执行顺序由cpu调度决定
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMainModeEvent(Object event) {}
上述事件将在三个线程中完成,分别是UI,thread1,thread2.每个线程中的执行内容和顺序如下:
UI
- Serializable 事件
 - Comparable 事件
 - String 事件
 
thread1
- CharSequence 事件
 
thread2
- Object 事件
 

7. postSticky
- postSticky
 
- 只保留最后一个投递的消息
 - 凡是在该事件投递之后注册的Object依然可以接受到Event,不论该Event是否被其他订阅过
 
SecoundActivity.java
public void onClick(View v) {
                Intent intent = new Intent(SecoundActivity.this,ThirdActivity.class);
                startActivity(intent);
                EventBus.getDefault().postSticky("sticky0");
            }
@Subscribe(sticky = true,threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(String event) {
        Log.i("SecoundActivity", "MAIN_ORDERED : Subscribe Recv String Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
    }ThirdActivity.java
@Subscribe(sticky = true,threadMode = ThreadMode.MAIN_ORDERED)
public void onMainModeEvent(String event) {
Log.i("ThirdActivity", "MAIN_ORDERED : Subscribe Recv String Event ,thread id: " + Thread.currentThread().getId() + ",event message:" + event);
}

                










