EventBus源码分析

1.定义注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

2.初始化
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

3.注册
    public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }
    findSubscriberMethods方法会把找到的监听方法封装成一个SubscriberMethod对象:

    public class SubscriberMethod {
        final Method method;//订阅方法
        final ThreadMode threadMode;//事件模型
        final Class<?> eventType;//事件类型
        final int priority;//优先级
        final boolean sticky;//是否为粘性事件
        /** Used for efficient comparison */
        String methodString;//方法字符串
      .......
    }
    findSubscriberMethods是怎么遭到被@Subscribe注解的方法呢?EventBus会将一个类中订阅方法的列表缓存起来,如果有直接返回,没有就通过编译时生成的代码或反射找到订阅方法列表

        List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        //从缓存中查询注册的类对应订阅方法列表
            List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
            //如果有直接返回
            if (subscriberMethods != null) {
                return subscriberMethods;
            }

            if (ignoreGeneratedIndex) {
                subscriberMethods = findUsingReflection(subscriberClass);
            } else {
            //使用编译时注解获取
                subscriberMethods = findUsingInfo(subscriberClass);
            }
            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;
            }
        }

         private void findUsingReflectionInSingleClass(FindState findState) {
                Method[] methods;
                try {
                //获取注册到EventBus类中所有方法
                    // 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
                    methods = findState.clazz.getMethods();
                    findState.skipSuperClasses = true;
                }
                //遍历所有方法
                for (Method method : methods) {
                    int modifiers = method.getModifiers();
                    //如果是public方法并且是费静态抽象方法
                    if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        //判断是否只有一个参数
                        if (parameterTypes.length == 1) {
                        //获取Subscribe注解
                            Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                            if (subscribeAnnotation != null) {
                            //创建SubscriberMethod对象保存
                                Class<?> eventType = parameterTypes[0];
                                if (findState.checkAdd(method, eventType)) {
                                    ThreadMode threadMode = subscribeAnnotation.threadMode();
                                    findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                            subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                                }
                            }
                        } 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);
                        }
                    } 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");
                    }
                }
            }
           4.订阅
             private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
             //获取订阅方法事件
                    Class<?> eventType = subscriberMethod.eventType;
                    //创建一个Subscription对象,一个订阅方法subscriberMethod对应一个Subscription
                    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
                    //获取对应事件Subscription集合
                    CopyOnWriteArrayList<Subscription> subscriptions =           subscriptionsByEventType.get(eventType);
                    //之前没有事件对应的集合,创建集合并加入subscriptionsByEventType
                    if (subscriptions == null) {
                        subscriptions = new CopyOnWriteArrayList<>();
                        subscriptionsByEventType.put(eventType, subscriptions);
                    } else {
                        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++) {
                    //根据优先级将newSubscription 加入集合,优先级越高越靠前
                        if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
                            subscriptions.add(i, newSubscription);
                            break;
                        }
                    }

                    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
                    if (subscribedEvents == null) {
                        subscribedEvents = new ArrayList<>();
                        typesBySubscriber.put(subscriber, subscribedEvents);
                    }
                    subscribedEvents.add(eventType);

                    if (subscriberMethod.sticky) {
                        if (eventInheritance) {
                            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);
                        }
                    }
                }
                5.反注册
                 public synchronized void unregister(Object subscriber) {
                 //获取一个订阅者订阅的事件类型集合
                        List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
                        if (subscribedTypes != null) {
                            for (Class<?> eventType : subscribedTypes) {
                            //通过事件类型和订阅者找到对应的Subscription然后清除
                                unsubscribeByEventType(subscriber, eventType);
                            }
                            //移除订阅者
                            typesBySubscriber.remove(subscriber);
                        } else {
                            Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
                        }
                    }
                    
                        private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
                        //获取事件类型的subscriptions 集合
                            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);
                                    //对比,如果是需要反注册的订阅者,则移除该subscription
                                    if (subscription.subscriber == subscriber) {
                                        subscription.active = false;
                                        subscriptions.remove(i);
                                        i--;
                                        size--;
                                    }
                                }
                            }
                        }

                
                6.发布
                post内部调用了postSingleEvent,postSingleEvent调用postSingleEventForEventType获取Subscription集合,遍历调用postToSubscription。
                 private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
                        CopyOnWriteArrayList<Subscription> subscriptions;
                        synchronized (this) {
                            subscriptions = subscriptionsByEventType.get(eventClass);
                        }
                        if (subscriptions != null && !subscriptions.isEmpty()) {
                            for (Subscription subscription : subscriptions) {
                                postingState.event = event;
                                postingState.subscription = subscription;
                                boolean aborted = false;
                                try {
                                    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;
                    }
                    postToSubscription里面根据订阅方法的线程模型来完成在那个线程执行订阅
                    
                        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 {
                                    //不是主线程,切换到主线程执行方法,内部是Handler
                                        mainThreadPoster.enqueue(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);
                            }
                        }
                        //反射执行订阅方法
                            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);
                                }
                            }
                            
                            
                            //Handler处理线程切换
                             void enqueue(Subscription subscription, Object event) {
                                    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
                                    synchronized (this) {
                                        queue.enqueue(pendingPost);
                                        if (!handlerActive) {
                                            handlerActive = true;
                                            if (!sendMessage(obtainMessage())) {
                                                throw new EventBusException("Could not send handler message");
                                            }
                                        }
                                    }
                                }
                            
                                @Override
                                public void handleMessage(Message msg) {
                                    boolean rescheduled = false;
                                    try {
                                        long started = SystemClock.uptimeMillis();
                                        while (true) {
                                            PendingPost pendingPost = queue.poll();
                                            if (pendingPost == null) {
                                                synchronized (this) {
                                                    // Check again, this time in synchronized
                                                    pendingPost = queue.poll();
                                                    if (pendingPost == null) {
                                                        handlerActive = false;
                                                        return;
                                                    }
                                                }
                                            }
                                            eventBus.invokeSubscriber(pendingPost);
                                            long timeInMethod = SystemClock.uptimeMillis() - started;
                                            if (timeInMethod >= maxMillisInsideHandleMessage) {
                                                if (!sendMessage(obtainMessage())) {
                                                    throw new EventBusException("Could not send handler message");
                                                }
                                                rescheduled = true;
                                                return;
                                            }
                                        }
                                    } finally {
                                        handlerActive = rescheduled;
                                    }
                                }
                                
                                 backgroundPoster.enqueue()来开启线程池
                                    public void enqueue(Subscription subscription, Object event) {
                                        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
                                        synchronized (this) {
                                            queue.enqueue(pendingPost);
                                            if (!executorRunning) {
                                                executorRunning = true;
                                                //执行线程池
                                                eventBus.getExecutorService().execute(this);
                                            }
                                        }
                                    }
                                    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值