github源碼分享:https://github.com/greenrobot/EventBus
官方圖解:

EventBus是Android和Java的發(fā)布/訂閱事件總線。
EventBus優(yōu)勢(shì):
1、簡(jiǎn)化了組件之間的通信:
將事件發(fā)送者和接收者分離
在活動(dòng),片段和后臺(tái)線程中表現(xiàn)良好
避免復(fù)雜且容易出錯(cuò)的依賴(lài)關(guān)系和生命周期問(wèn)題
2、使您的代碼更簡(jiǎn)潔
3、很快
4、很?。s50kb)
5、已經(jīng)通過(guò)100,000,000+安裝的應(yīng)用程序在實(shí)踐中得到證實(shí)
6、具有交付線程,用戶(hù)優(yōu)先級(jí)等高級(jí)功能;
總結(jié):
EventBus的使用比較簡(jiǎn)單,可以按照官網(wǎng)圖的方式來(lái)進(jìn)行理解。EventBus相當(dāng)于郵箱,發(fā)布者直接把信息放到信箱,信箱會(huì)自動(dòng)把信息發(fā)給訂閱了的人。
這里簡(jiǎn)單梳理一下EventBus的主要邏輯:
1、EventBus對(duì)象的構(gòu)建,使用單列模式創(chuàng)建
2、注冊(cè)事件,包含粘性事件
3、發(fā)布消息
4、接受消息
5、反注冊(cè)事件,避免內(nèi)存泄漏
(一)、EventBus構(gòu)造方法原理

這里就簡(jiǎn)單的使用單例模式實(shí)現(xiàn)
EventBus.java
private static EventBus instance;
public static EventBus getDefault() {
? ? if (instance == null) {
? ? ? ? synchronized (EventBus.class) {
? ? ? ? ? ? if (instance == null) {
? ? ? ? ? ? ? ? instance = new EventBus();
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return instance;
}
(二)、注冊(cè)事件

注冊(cè)就是將此類(lèi)中的所有的帶Subscriber注解的方法緩存起來(lái),以便發(fā)布消息時(shí)調(diào)用;
我們也是簡(jiǎn)單的模擬實(shí)現(xiàn)注冊(cè),不包含粘性事件的注冊(cè)
需求:從AActivity跳轉(zhuǎn)到BActivity中,在BActivity中發(fā)布消息給AActivity;
//比如在AActivity接受事件,我們就在AActivity中注冊(cè)一個(gè)接收消息的方法
如:
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
? ? super.onCreate(savedInstanceState);
? ? setContentView(R.layout.activity_main);
? //注冊(cè)
? ? EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void handleMessages(EventBean eventBean) {
? ? Log.d("======>", eventBean.toString());
? ? Log.d("======", "send: MainActivity " + Thread.currentThread().getName());
}
Subscribe是一個(gè)注解類(lèi),用來(lái)標(biāo)記一個(gè)方法
Subscribe.java
@Documented
@Retention(RetentionPolicy.RUNTIME)// 表示為運(yùn)行時(shí)注解
@Target({ElementType.METHOD})
public @interface Subscribe {
? ? // 指定事件訂閱方法的線程模式,即在那個(gè)線程執(zhí)行事件訂閱方法處理事件,默認(rèn)為POSTING
? ? ThreadMode threadMode() default ThreadMode.POSTING;
? ? // 是否支持粘性事件,默認(rèn)為false
? ? boolean sticky() default false;
? ? // 指定事件訂閱方法的優(yōu)先級(jí),默認(rèn)為0,如果多個(gè)事件訂閱方法可以接收相同事件的,則優(yōu)先級(jí)高的先接收到事件
? ? int priority() default 0;
}
ThreadMode是一個(gè)枚舉類(lèi),用來(lái)標(biāo)記此方法在那個(gè)線程執(zhí)行
ThreadMode.java
public enum ThreadMode {
? ? POSTING,//默認(rèn)的線程模式,在那個(gè)線程發(fā)送事件就在對(duì)應(yīng)線程處理事件,避免了線程切換,效率高。
? ? MAIN,//如在主線程(UI線程)發(fā)送事件,則直接在主線程處理事件;如果在子線程發(fā)送事件,則先將事件入隊(duì)列,然后通過(guò) Handler 切換到主線程,依次處理事件。
? ? MAIN_ORDERED,//無(wú)論在那個(gè)線程發(fā)送事件,都先將事件入隊(duì)列,然后通過(guò) Handler 切換到主線程,依次處理事件。
? ? BACKGROUND,//如果在主線程發(fā)送事件,則先將事件入隊(duì)列,然后通過(guò)線程池依次處理事件;如果在子線程發(fā)送事件,則直接在發(fā)送事件的線程處理事件。
? ? ASYNC//無(wú)論在那個(gè)線程發(fā)送事件,都將事件入隊(duì)列,然后通過(guò)線程池處理。
}
private Map<Object, List<SubscriberMethod>> cacheMap;// 用來(lái)緩存注冊(cè)\訂閱的事件
public void register(Object subscriber) {
? ? // 檢查此類(lèi)是否已經(jīng)注冊(cè)
? ? List<SubscriberMethod> subscriberMethods = cacheMap.get(subscriber);
? ? if (subscriberMethods == null) {
? ? ? ? subscriberMethods = findSubscriberMethods(subscriber);
? ? ? ? cacheMap.put(subscriber, subscriberMethods);
? ? }
}
/**
* 查找此類(lèi)以及父類(lèi)中所有帶Subscriber注釋的方法
* @param subscriber
* @return
*/
private List<SubscriberMethod> findSubscriberMethods(Object subscriber) {
? ? List<SubscriberMethod> list = new ArrayList<>();
? ? Class<?> clazz = subscriber.getClass();
? ? while (clazz != null) {
? ? ? ? String name = clazz.getName();
? ? ? ? // 過(guò)濾系統(tǒng)類(lèi)
? ? ? ? if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? Method[] methods = clazz.getDeclaredMethods();// 獲取此類(lèi)中所有的的方法(包含繼承父類(lèi)中的)
? ? ? ? for (Method method : methods) {
? ? ? ? ? ? Subscribe annotation = method.getAnnotation(Subscribe.class);// 找到方法上的注解參數(shù)
? ? ? ? ? ? if (annotation == null) {
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? //獲取所有帶有Subscribe注解的方法中的參數(shù)類(lèi)型
? ? ? ? ? ? Class<?>[] parameterTypes = method.getParameterTypes();
? ? ? ? ? ? if (parameterTypes.length != 1) {// 只記錄帶有一個(gè)參數(shù)的方法
? ? ? ? ? ? ? ? Log.e("error", "EventBus only support one para");
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? ThreadMode threadMode = annotation.threadMode();
? ? ? ? ? ? SubscriberMethod subscriberMethod = new SubscriberMethod(method, parameterTypes[0], threadMode, 0, false);
? ? ? ? ? ? list.add(subscriberMethod);
? ? ? ? }
? ? ? ? clazz = clazz.getSuperclass();
? ? }
? ? return list;
}
SubscriberMethod.java 帶有注解的方法對(duì)象
public class SubscriberMethod {
? ? private Method method;
? ? private ThreadMode threadMode;
? ? private Class<?> eventType;
? ? private int priority;
? ? private boolean sticky;
? ? /**
? ? * Used for efficient comparison
? ? */
? ? String methodString;
? ? public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {
? ? ? ? this.method = method;
? ? ? ? this.threadMode = threadMode;
? ? ? ? this.eventType = eventType;
? ? ? ? this.priority = priority;
? ? ? ? this.sticky = sticky;
? ? }
? ? @Override
? ? public boolean equals(Object other) {
? ? ? ? if (other == this) {
? ? ? ? ? ? return true;
? ? ? ? } else if (other instanceof SubscriberMethod) {
? ? ? ? ? ? checkMethodString();
? ? ? ? ? ? SubscriberMethod otherSubscriberMethod = (SubscriberMethod) other;
? ? ? ? ? ? otherSubscriberMethod.checkMethodString();
? ? ? ? ? ? // Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6
? ? ? ? ? ? return methodString.equals(otherSubscriberMethod.methodString);
? ? ? ? } else {
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
? ? private synchronized void checkMethodString() {
? ? ? ? if (methodString == null) {
? ? ? ? ? ? // Method.toString has more overhead, just take relevant parts of the method
? ? ? ? ? ? StringBuilder builder = new StringBuilder(64);
? ? ? ? ? ? builder.append(method.getDeclaringClass().getName());
? ? ? ? ? ? builder.append('#').append(method.getName());
? ? ? ? ? ? builder.append('(').append(eventType.getName());
? ? ? ? ? ? methodString = builder.toString();
? ? ? ? }
? ? }
? ? @Override
? ? public int hashCode() {
? ? ? ? return method.hashCode();
? ? }
? ? public Method getMethod() {
? ? ? ? return method;
? ? }
? ? public ThreadMode getThreadMode() {
? ? ? ? return threadMode;
? ? }
? ? public Class<?> getEventType() {
? ? ? ? return eventType;
? ? }
? ? public int getPriority() {
? ? ? ? return priority;
? ? }
? ? public boolean isSticky() {
? ? ? ? return sticky;
? ? }
? ? public String getMethodString() {
? ? ? ? return methodString;
? ? }
}
以上就是事件注冊(cè)\訂閱的完整流程
(三)、發(fā)布消息

SecondActivity.java中任意位置
EventBus.getDefault().post(new EventBean("EventBusMassage", 111111111));
EventBus.java
public void post(final Object obj) {
? ? // 從注冊(cè)事件中循環(huán)查詢(xún)
? ? Set<Object> objects = cacheMap.keySet();
? ? Iterator<Object> iterator = objects.iterator();
? ? while (iterator.hasNext()) {
? ? ? ? final Object next = iterator.next();
? ? ? ? List<SubscriberMethod> list = cacheMap.get(next);
? ? ? ? for (final SubscriberMethod subsMethod : list) {
? ? ? ? ? ? // 獲取到的類(lèi)的類(lèi)型是否和傳入或者發(fā)送消息的類(lèi)對(duì)象類(lèi)型相同
? ? ? ? ? ? if (subsMethod.getEventType().isAssignableFrom(obj.getClass())) {
? ? ? ? ? ? ? ? switch (subsMethod.getThreadMode()) {
? ? ? ? ? ? ? ? ? ? case MAIN:
? ? ? ? ? ? ? ? ? ? ? ? // 主線程---》主線程
? ? ? ? ? ? ? ? ? ? ? ? if (Looper.myLooper() == Looper.getMainLooper()) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? invoke(subsMethod, next, obj);
? ? ? ? ? ? ? ? ? ? ? ? } else { // 子線程---》主線程
? ? ? ? ? ? ? ? ? ? ? ? ? ? mHandler.post(new Runnable() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invoke(subsMethod, next, obj);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? case BACKGROUND:
? ? ? ? ? ? ? ? ? ? ? ? // 主線程---》子線程
? ? ? ? ? ? ? ? ? ? ? ? if (Looper.myLooper() == Looper.getMainLooper()) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ExecutorService executorService = Executors.newFixedThreadPool(10);
? ? ? ? ? ? ? ? ? ? ? ? ? ? executorService.execute(new Runnable() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invoke(subsMethod, next, obj);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? } else { // 子線程---》子線程
? ? ? ? ? ? ? ? ? ? ? ? ? ? invoke(subsMethod, next, obj);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
// 方法調(diào)用并執(zhí)行
private void invoke(SubscriberMethod subsMethod, Object next, Object obj) {
? ? Method method = subsMethod.getMethod();
? ? try {
? ? ? ? method.invoke(next, obj);
? ? } catch (IllegalAccessException e) {
? ? ? ? e.printStackTrace();
? ? } catch (InvocationTargetException e) {
? ? ? ? e.printStackTrace();
? ? }
}
(四)、接受消息
MainActivity.java
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void handleMessages(EventBean eventBean) {
? ? Log.d("======>", eventBean.toString());
? ? Log.d("======", "handleMessages: MainActivity " + Thread.currentThread().getName());
}
(五)、注銷(xiāo)事件
MainActivity.java
@Override
protected void onDestroy() {
? ? super.onDestroy();
? ? EventBus.getDefault().unregister(this);
}
EventBus.java
// 注銷(xiāo)事件
public void unregister(Object subscriber) {
? ? List<SubscriberMethod> subscribedTypes = cacheMap.get(subscriber);
? ? if (subscribedTypes != null) {
? ? ? ? cacheMap.remove(subscriber);
? ? } else {
? ? ? ? Log.e("error", "Subscriber to unregister was not registered before: " + subscriber.getClass());
? ? }
}