Java教程

简谈源码-EventBus(v3.2.0)

本文主要是介绍简谈源码-EventBus(v3.2.0),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

EventBus官网
在这里插入图片描述

使用方法

步骤一、定义事件

订阅的事件类

public static class MessageEvent { /* Additional fields if needed */ }

步骤二、准备订阅者

  1. 订阅方法,需要@Subscribe注解声明,可以设置处理该事件的线程等

    @Subscribe(threadMode = ThreadMode.MAIN)  
    public void onMessageEvent(MessageEvent event) {/* Do something */};
    
  2. 订阅者的注册和反注册,如在Activity和Fragment的中添加

     @Override public void onStart() {
         super.onStart();
         EventBus.getDefault().register(this);
     }
    
     @Override public void onStop() {
         super.onStop();
         EventBus.getDefault().unregister(this);
     }
    

步骤三、发送事件

post发送事件后,上述步骤2.中的订阅方法可以接受事件并回调处理

 EventBus.getDefault().post(new MessageEvent());

概述

通过单例和建造者创建EventBus实例;

通过@Subscribe添加订阅方法,可以设置订阅方法的优先级,所属处理线程,是否是粘性;

register注册方法中,通过两种方式获取订阅者中的所有订阅方法:①通过运行时反射,收集被@Subscribe注解声明的方法;②通过编译时索引,即apt(AbstractProcessor的process(Set<? extends TypeElement> annotations, RoundEnvironment env))方法,将被@Subscribe注解声明的方法,编写至build下的java文件;

subscribe订阅方法,将当前订阅者内的所有订阅方法放入subscribedEvents集合;

post推送event事件后,根据存储的订阅信息集合查找匹配的对象,进行invoke反射调用订阅了event事件的订阅方法;

源码走读

1.订阅注解@Subscribe

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    
    /*订阅者在哪种线程中做处理*/
    //ThreadMode包含
    //1.POSTING-事件发布者和订阅者处于同一线程,没有线程切换,开销最小
    //2.MAIN-订阅方法于主线程中处理
    //3.MAIN_ORDERED-订阅者于主线程中处理,并按优先级队列有序处理
    //4.BACKGROUND-订阅者于子线程中处理,并按优先级队列有序处理
    //5.ASYNC-订阅者于线程池中处理,适合网络访问
    ThreadMode threadMode() default ThreadMode.POSTING;

    /*是否是粘性事件*/
    boolean sticky() default false;

    /*同一线程中,优先级高的订阅者先收到事件*/
    int priority() default 0;
}

2.创建EventBus实例EventBus.getDefault()

使用设计模式:单例和建造者

class EventBus {
   //...
   public static EventBus getDefault() {
        EventBus instance = defaultInstance;
        if (instance == null) {
            synchronized (EventBus.class) {
                instance = EventBus.defaultInstance;
                if (instance == null) {
                    instance = EventBus.defaultInstance = new EventBus();
                }
            }
        }
        return instance;
    }

    //...

    EventBus(EventBusBuilder builder) {
        logger = builder.getLogger();
        subscriptionsByEventType = new HashMap<>();
        typesBySubscriber = new HashMap<>();
        stickyEvents = new ConcurrentHashMap<>();
        mainThreadSupport = builder.getMainThreadSupport();
        mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
        backgroundPoster = new BackgroundPoster(this);
        asyncPoster = new AsyncPoster(this);
        indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
        subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
                builder.strictMethodVerification, builder.ignoreGeneratedIndex);
        logSubscriberExceptions = builder.logSubscriberExceptions;
        logNoSubscriberMessages = builder.logNoSubscriberMessages;
        sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
        sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
        throwSubscriberException = builder.throwSubscriberException;
        eventInheritance = builder.eventInheritance;
        executorService = builder.executorService;
    }

   //...
}

3.EventBus的注册.register(this)

主要变量和初始化参考参数

//{msg1: [{firstActivity, onMsg1(msg1)}]}
//{msg2: [{firstActivity, onMsg2(msg2)}, {secondActivity, onMsg2(msg2)}]}
//{msg3: [{secondActivity, onMsg3(msg3)}]}
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
//{firstActivity: [Msg1, Msg2]}
//{secondActivity: [Msg2, Msg3]}
private final Map<Object, List<Class<?>>> typesBySubscriber;


final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
//{msg1: onMsg1(msg1)}
//{msg2: onMsg2(msg2)}
//{msg3: onMsg3(msg3)}
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
//{onMsg1()>0001, firstActivity}
//{onMsg2()>0002, firstActivity}
//{onMsg2()>0002, secondActivity}
//{onMsg3()>0003, secondActivity}
final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();

注册方法入口

/** 订阅者需注册才能接收事件,且不再使用时须解注册;订阅方法必须被@Subscribe注解声明,可以配置其线程和优先级 */
public void register(Object subscriber) {
    //subscriber是订阅者[如firstActivity或secondActivity]
    Class<?> subscriberClass = subscriber.getClass();
    //找出当前subscriber内的所有订阅方法
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        //遍历当前subscriber内的订阅方法
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            //开始订阅
            subscribe(subscriber, subscriberMethod);
        }
    }
}

3.1找出订阅者内的所有订阅方法findSubscriberMethods(subscriberClass)

//如找出firstActivity中的onMsg1/onMsg2订阅方法
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
    //缓存中取订阅方法[METHOD_CACHE:ConcurrentHashMap<Class<?>, List<SubscriberMethod>>]
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    if (subscriberMethods != null) {
        return subscriberMethods;
    }

    //true=>运行时反射获取订阅方法
    //false=>编译时生成订阅方法索引
    if (ignoreGeneratedIndex) {
        subscriberMethods = findUsingReflection(subscriberClass);
    } else {
        subscriberMethods = findUsingInfo(subscriberClass);
    }
    //若当前activity或fragment中未定义订阅方法则异常提示
    if (subscriberMethods.isEmpty()) {
        throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation");
        //将当前订阅者内的所有订阅方法置于缓存中
    } else {
        METHOD_CACHE.put(subscriberClass, subscriberMethods);
        return subscriberMethods;
    }
}
3.1.1方式一、反射
private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
    FindState findState = prepareFindState();
    findState.initForSubscriber(subscriberClass);
    while (findState.clazz != null) {
        //通过反射找出订阅者内所有的订阅方法
        findUsingReflectionInSingleClass(findState);
        findState.moveToSuperclass();
    }
    return getMethodsAndRelease(findState);
}

private void findUsingReflectionInSingleClass(FindState findState) {
    Method[] methods;
    try {
        // This is faster than getMethods, especially when subscribers are fat classes like Activities
        //获取订阅者类中所有方法
        methods = findState.clazz.getDeclaredMethods();
    } catch (Throwable th) {
        // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
        try {
            //获取订阅者类及其父类中所有方法
            methods = findState.clazz.getMethods();
        } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
            String msg = "Could not inspect methods of " + findState.clazz.getName();
            if (ignoreGeneratedIndex) {
                msg += ". Please consider using EventBus annotation processor to avoid reflection.";
            } else {
                msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
            }
            throw new EventBusException(msg, error);
        }
        //getMethods()方法中已获取父类方法=>所以此处设置跳过父类检查
        findState.skipSuperClasses = true;
    }

    //遍历所有方法
    for (Method method : methods) {
        //滤出public修饰的方法[public xxMethod(...) {}]
        int modifiers = method.getModifiers();
        if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            //滤出只有一个参数的方法[public xxMethod(Object obj) {}]
            if (parameterTypes.length == 1) {
                //滤出被@Subscribe注解声明的方法[@Subscribe public xxMethod(Object obj) {}]
                Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                if (subscribeAnnotation != null) {
                    //eventType为方法[@Subscribe public xxMethod(Object obj) {}]中的参数类型Object
                    //如方法[@Subscribe public void onMessageEvent(MessageEvent event) {}]中的MessageEvent
                    Class<?> eventType = parameterTypes[0];
                    //订阅者与订阅方法集合是否已添加当前method和eventType对
                    if (findState.checkAdd(method, eventType)) {
                        //checkAdd返回true即该method和eventType键值对不在subscriberMethods[订阅者与订阅方法集合]中
                        //=>根据@Subscribe注解属性并创建SubscriberMethod实例添加至subscriberMethods中
                        ThreadMode threadMode = subscribeAnnotation.threadMode();
                        findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                    }
                }
                //提示被@Subscribe注解声明的方法必须有且只能有一个参数
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                throw new EventBusException("@Subscribe method " + methodName +
                        "must have exactly 1 parameter but has " + parameterTypes.length);
            }
            //提示被@Subscribe注解声明的方法必须是被public修饰的,且不能被static和abstract修饰
        } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
            String methodName = method.getDeclaringClass().getName() + "." + method.getName();
            throw new EventBusException(methodName +
                    " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
        }
    }
}

boolean checkAdd(Method method, Class<?> eventType) {
    // 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required.
    // Usually a subscriber doesn't have methods listening to the same event type.
    /*
        关于Object obj = map.put(key);=>若key对应值不存在,则返回null;若key对应值存在,则回原先存储的value值,示例如下
        Map<String, String> map = new HashMap<>();
        String put1 = map.put("name", "Ashe");
        System.out.println("put1:" + put1);//put1:null
        String put2 = map.put("name", "Annie");
        System.out.println("put2:" + put2);//put2:Ashe
     */
    //如订阅者有如下三个订阅方法
    //@Subscribe(...) public void listen1(NewsMessage msg) {}
    //@Subscribe(...) public void listen2(NewsMessage msg) {}
    //@Subscribe(...) public void listen3(WeatherMessage msg) {}
    //第一次:put(newsMessage, listen1) => existing == null => return true => 调用上述findState.subscriberMethods.add方法
    //第二次:put(newsMessage, listen2) => existing == listen1 => else {...}
    //第三次:put(weatherMessage, listen3) => existing == null => return true => 调用上述findState.subscriberMethods.add方法
    Object existing = anyMethodByEventType.put(eventType, method);
    if (existing == null) {
        return true;
    } else {
        if (existing instanceof Method) {
            if (!checkAddWithMethodSignature((Method) existing, eventType)) {
                // Paranoia check
                throw new IllegalStateException();
            }
            // Put any non-Method object to "consume" the existing Method
            anyMethodByEventType.put(eventType, this);
        }
        return checkAddWithMethodSignature(method, eventType);
    }
}

private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
    methodKeyBuilder.setLength(0);
    methodKeyBuilder.append(method.getName());
    methodKeyBuilder.append('>').append(eventType.getName());

    //订阅方法的标识
    String methodKey = methodKeyBuilder.toString();
    //订阅方法所在的订阅者类
    Class<?> methodClass = method.getDeclaringClass();
    //将方法标识和订阅者类添加至subscriberClassByMethodKey集合
    Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
    /*
        isAssignableFrom(clz)从类继承角度判断是否为clz的父类
        instanceof clz从实例继承角度判断是否为clz的子类
     */
    //subscriberClassByMethodKey中第一次添加订阅方法和订阅者类||订阅方法及其父类已被添加至subscriberClassByMethodKey中
    //即subscriberClassByMethodKey之前并未添加该订阅方法和该子类信息对
    if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
        // Only add if not already found in a sub class
        //调用上述findState.subscriberMethods.add方法
        return true;
    } else {
        // Revert the put, old class is further down the class hierarchy
        subscriberClassByMethodKey.put(methodKey, methodClassOld);
        return false;
    }
}
3.1.2方式二、索引

用法参考=>https://greenrobot.org/eventbus/documentation/subscriber-index/

配置好后build项目,build->generated->ap_generated_sources->debug->out->com.example.myapp目录下生成MyEventBusIndex类文件;可以看到,通过apt的process方法,在编译时生成了所有订阅方法

package com.example.myapp;

import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberMethodInfo;
import org.greenrobot.eventbus.meta.SubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberInfoIndex;

import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Map;

/** This class is generated by EventBus, do not edit. */
public class MyEventBusIndex implements SubscriberInfoIndex {
    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();

        putIndex(new SimpleSubscriberInfo(cc.catface.eventbus.MainActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onName", cc.catface.eventbus.NameMsg.class, ThreadMode.MAIN_ORDERED, 7, true),
            new SubscriberMethodInfo("onAge", cc.catface.eventbus.AgeMsg.class),
            new SubscriberMethodInfo("onCommon", cc.catface.eventbus.CommonMsg.class),
            new SubscriberMethodInfo("onImpl", cc.catface.eventbus.MsgImpl.class),
            new SubscriberMethodInfo("onI", cc.catface.eventbus.IMsg.class),
        }));

    }

    private static void putIndex(SubscriberInfo info) {
        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
    }

    @Override
    public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
        if (info != null) {
            return info;
        } else {
            return null;
        }
    }
}

EventBus中收集上述在build生成的订阅方法信息

/*根据订阅者类找到所有订阅方法[如根据firstActivity找到onMsg1/onMsg2]*/
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
    FindState findState = prepareFindState();
    //置findState的subscriberClass==clazz=firstActivity
    findState.initForSubscriber(subscriberClass);
    //查找firstActivity
    while (findState.clazz != null) {
        //
        findState.subscriberInfo = getSubscriberInfo(findState);
        if (findState.subscriberInfo != null) {
            SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
            for (SubscriberMethod subscriberMethod : array) {
                if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                    findState.subscriberMethods.add(subscriberMethod);
                }
            }
        } else {
            findUsingReflectionInSingleClass(findState);
        }
        //查找父类
        findState.moveToSuperclass();
    }
    return getMethodsAndRelease(findState);
}

/*findState中clazz为firstActivity*/
private SubscriberInfo getSubscriberInfo(FindState findState) {
    //查找父类中的订阅对象[如firstActivity的父类baseActivity]
    if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
        SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
        if (findState.clazz == superclassInfo.getSubscriberClass()) {
            return superclassInfo;
        }
    }
    if (subscriberInfoIndexes != null) {
        for (SubscriberInfoIndex index : subscriberInfoIndexes) {
            //调用MyEventBusIndex的getSubscriberInfo方法获取编译时生成的订阅方法索引
            SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
            if (info != null) {
                return info;
            }
        }
    }
    return null;
}

3.2事件订阅subscribe(subscriber, subscriberMethod)

如将firstActivity中的onMsg1/onMsg2订阅方法添加至subscribedEvents集合

// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    //订阅事件类型[如Msg1]
    Class<?> eventType = subscriberMethod.eventType;
    //创建订阅对象[如new Subscription(firstActivity, onMsg1(msg1))]
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    //订阅了Msg1事件的订阅集合subscriptions
    //一开始是空的
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions == null) {
        subscriptions = new CopyOnWriteArrayList<>();
        //将Msg1和新建的subscriptions空集合信息对放入map中
        subscriptionsByEventType.put(eventType, subscriptions);
    } else {
        //subscriptions集合中已有当前订阅对象=>异常提示firstActivity已有监听Msg1的订阅方法
        if (subscriptions.contains(newSubscription)) {
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                    + eventType);
        }
    }

    int size = subscriptions.size();
    for (int i = 0; i <= size; i++) {
        //根据优先级添加订阅对象至subscriptions
        if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
            subscriptions.add(i, newSubscription);
            break;
        }
    }

    //查找订阅者订阅的所有事件类型[如firstActivity订阅的Msg1, Msg2]
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    //若该订阅者的订阅方法类型列表为空
    if (subscribedEvents == null) {
        //给该订阅者加一个空的订阅的事件类型集合
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    //添加订阅的事件类型[如Msg1]
    subscribedEvents.add(eventType);

    /**
     * 粘性事件:事件发送后再订阅该事件也能接收
     */
    if (subscriberMethod.sticky) {
        if (eventInheritance) {
            // Existing sticky events of all subclasses of eventType have to be considered.
            // Note: Iterating over all events may be inefficient with lots of sticky events,
            // thus data structure should be changed to allow a more efficient lookup
            // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
            Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry<Class<?>, Object> entry : entries) {
                Class<?> candidateEventType = entry.getKey();
                if (eventType.isAssignableFrom(candidateEventType)) {
                    Object stickyEvent = entry.getValue();
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
            //根据事件类型获取粘性事件
            Object stickyEvent = stickyEvents.get(eventType);
            //检查并发送粘性事件
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}

EventBus的反注册.unregister(this)

如unregister(firstActivity),根据firstActivity获取typesBySubscriber为[Msg1, Msg2],遍历调用unsubscribeByEventType(firstActivity, [Msg1, Msg2]),调用subscriptionsByEventType.get(Msg1, Msg2),得到的subscriptions分别为[firstActivity]和[firstActivity, secondActivity],然后判断并移除,最后的subscriptions分别为[]和[secondActivity]

/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
    //subscribedTypes为subscriber内所有的订阅事件类型[如firstActivity内订阅了Msg1,Msg2]
    //其中typesBySubscriber在订阅者调用register(this)方法注册后会赋值所以此处才必不为空
    List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
    if (subscribedTypes != null) {
        for (Class<?> eventType : subscribedTypes) {
            unsubscribeByEventType(subscriber, eventType);
        }
        typesBySubscriber.remove(subscriber);
    } else {
        //异常提示未注册
        logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
    }
}

/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
    //获取所有订阅了事件类型为eventType的订阅者
    List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions != null) {
        int size = subscriptions.size();
        for (int i = 0; i < size; i++) {
            Subscription subscription = subscriptions.get(i);
            //将当前订阅者从eventType事件类型的订阅者列表中移除
            if (subscription.subscriber == subscriber) {
                subscription.active = false;
                subscriptions.remove(i);
                i--;
                size--;
            }
        }
    }
}

EventBus发送事件.post(new MessageEvent())

/** Posts the given event to the event bus. */
public void post(Object event) {
    //currentPostingThreadState是事件信息的队列
    PostingThreadState postingState = currentPostingThreadState.get();
    List<Object> eventQueue = postingState.eventQueue;
    //将事件添加至事件队列
    eventQueue.add(event);

    if (!postingState.isPosting) {
        //检查是否在主线程发送事件
        postingState.isMainThread = isMainThread();
        //设置事件发送状态
        postingState.isPosting = true;
        if (postingState.canceled) {
            throw new EventBusException("Internal error. Abort state was not reset");
        }
        try {
            while (!eventQueue.isEmpty()) {
                //发送事件
                postSingleEvent(eventQueue.remove(0), postingState);
            }
        } finally {
            //重置事件的发送状态
            postingState.isPosting = false;
            postingState.isMainThread = false;
        }
    }
}

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    //事件类型[如msg1事件的类型为Msg1]
    Class<?> eventClass = event.getClass();
    boolean subscriptionFound = false;
    if (eventInheritance) {
        //如firstActivity中订阅了Msg1事件/Msg1的父类如BaseMsg事件/Msg1的接口如IMsg事件的订阅方法都会接受事件
        //如有事件Msg1 extends BaseMsg implements IMsg
        //在firstActivity中有订阅方法onMsg1(Msg1)/onBaseMsg(BaseMsg)/onIMsg(IMsg)
        //此时post(Msg1)则firstActivity中的三个订阅方法都会回调
        List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
        int countTypes = eventTypes.size();
        for (int h = 0; h < countTypes; h++) {
            Class<?> clazz = eventTypes.get(h);
            //发送event事件
            subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
        }
    } else {
        subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
    }
    //没有订阅event事件的订阅方法
    if (!subscriptionFound) {
        if (logNoSubscriberMessages) {
            logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
        }
        if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
                eventClass != SubscriberExceptionEvent.class) {
            post(new NoSubscriberEvent(this, event));
        }
    }
}

private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
    CopyOnWriteArrayList<Subscription> subscriptions;
    synchronized (this) {
        //订阅了Msg1事件的订阅方法[如onMsg1/onBaseMsg/onIMsg]
        subscriptions = subscriptionsByEventType.get(eventClass);
    }
    if (subscriptions != null && !subscriptions.isEmpty()) {
        for (Subscription subscription : subscriptions) {
            postingState.event = event;
            postingState.subscription = subscription;
            boolean aborted;
            try {
                //将事件发送给订阅对象[如(firstActivity, onMsg1(msg1)-main), msg1, msg1事件post的线程在thread]
                postToSubscription(subscription, event, postingState.isMainThread);
                aborted = postingState.canceled;
            } finally {
                //重置状态
                postingState.event = null;
                postingState.subscription = null;
                postingState.canceled = false;
            }
            if (aborted) {
                break;
            }
        }
        return true;
    }
    return false;
}

//[如(firstActivity, onMsg1(msg1)-main), msg1, msg1事件post的线程在thread]
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
    switch (subscription.subscriberMethod.threadMode) {
        case POSTING:
            invokeSubscriber(subscription, event);
            break;
        case MAIN:
            if (isMainThread) {
                //若onMsg1(msg1)订阅方法被定义在main线程处理且msg1事件发送线程也在main线程
                //反射调用方法[如onMsg1.invoke(firstActivity, msg1)]
                invokeSubscriber(subscription, event);
            } else {
                //若onMsg1(msg1)订阅方法被定义在main线程处理且msg1事件发送线程在子线程=>Handler线程调度
                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);
    }
}

反射调用订阅了event事件的订阅方法

void invokeSubscriber(Subscription subscription, Object event) {
    try {
        //反射调用方法
        subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
    } catch (InvocationTargetException e) {
        handleSubscriberException(subscription, event, e.getCause());
    } catch (IllegalAccessException e) {
        throw new IllegalStateException("Unexpected exception", e);
    }
}

粘性事件调用流程

粘性:即可以先post发送事件,在post后注册的订阅方法也可以接收到事件(从消息缓存中获取已发送的事件),并开始消费

EventBus.getDefault().postSticky(new Msg());

public void postSticky(Object event) {
    synchronized (stickyEvents) {
        //缓存粘性事件
        stickyEvents.put(event.getClass(), event);
    }
    // Should be posted after it is putted, in case the subscriber wants to remove immediately
    post(event);
}

若当前订阅方法被声明为粘性,则在订阅后立即执行

// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    //...

    //当前订阅方法是粘性属性,直接调用该订阅方法
    if (subscriberMethod.sticky) {
        if (eventInheritance) {
            // Existing sticky events of all subclasses of eventType have to be considered.
            // Note: Iterating over all events may be inefficient with lots of sticky events,
            // thus data structure should be changed to allow a more efficient lookup
            // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
            Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry<Class<?>, Object> entry : entries) {
                Class<?> candidateEventType = entry.getKey();
                if (eventType.isAssignableFrom(candidateEventType)) {
                    Object stickyEvent = entry.getValue();
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
            Object stickyEvent = stickyEvents.get(eventType);
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}
这篇关于简谈源码-EventBus(v3.2.0)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!