ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

简谈源码-EventBus(v3.2.0)

2021-11-11 14:00:24  阅读:157  来源: 互联网

标签:v3.2 订阅 eventType 简谈 findState 源码 new null event


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);
        }
    }
}

标签:v3.2,订阅,eventType,简谈,findState,源码,new,null,event
来源: https://blog.csdn.net/itCatface/article/details/121266190

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有