EventBus源码分析

本文深入探讨了EventBus的内部实现,包括ThreadMode的五种线程模式、Subscribe注解的使用、SubscriberMethod与注解的映射、Subscription订阅机制、PendingPost及队列管理、不同Poster的线程策略,还有SubscriberInfo等核心组件的详细解析。
摘要由CSDN通过智能技术生成

​​​​​​​

 

1.ThreadMode定义了5种线程模式

/**
 * Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus.
 * EventBus takes care of threading independently from the posting thread.
 * 
 * @see EventBus#register(Object)
 * @author Markus
 * ok
 */
public enum ThreadMode {
    /**
     * Subscriber will be called directly in the same thread, which is posting the event. This is the default. Event delivery
     * implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for
     * simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers
     * using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
     * 订阅者将在发布事件的同一线程中直接调用。 这是默认设置。 事件传递意味着最少的开销,因为它完全避免了线程切换。
     * 因此,对于已知在很短的时间内完成而不需要主线程的简单任务,这是推荐的模式。 使用此模式的事件处理程序必须快速
     * 返回以避免阻塞可能是主线程的发布线程。
     *
     * 默认的线程模式,在哪个线程发送事件就在对应线程处理事件,避免了线程切换,效率高。
     */
    POSTING,

    /**
     * On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is
     * the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event
     * is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread.
     * If not on Android, behaves the same as {@link #POSTING}.
     * 在 Android 上,订阅者将在 Android 的主线程(UI 线程)中调用。
     * 如果发帖线程是主线程,则直接调用订阅者方法,阻塞发帖线程。否则,事件将排队等待传递(非阻塞)。
     * 使用这种模式的订阅者必须快速返回以避免阻塞主线程。 如果不是在 Android 上,则行为与 {@link #POSTING} 相同。
     *
     * 如在主线程(UI线程)发送事件,则直接在主线程处理事件;如果在子线程发送事件,则先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
     */
    MAIN,

    /**
     * On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN},
     * the event will always be queued for delivery. This ensures that the post call is non-blocking.
     * 在 Android 上,订阅者将在 Android 的主线程(UI 线程)中调用。 与 {@link #MAIN} 不同,事件将始终排队等待交付。 这确保了 post 调用是非阻塞的。
     *
     * 无论在哪个线程发送事件,都将事件加入到队列中,然后通过Handler切换到主线程,依次处理事件。
     */
    MAIN_ORDERED,

    /**
     * On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods
     * will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single
     * background thread, that will deliver all its events sequentially. Subscribers using this mode should try to
     * return quickly to avoid blocking the background thread. If not on Android, always uses a background thread.
     * 在 Android 上,订阅者将在后台线程中调用。 如果发帖线程不是主线程,则将在发帖线程中直接调用订阅者方法。
     * 如果发布线程是主线程,则 EventBus 使用单个后台线程,它将按顺序传递其所有事件。 使用这种模式的订阅者应该尝试快速返回以避免阻塞后台线程。
     * 如果不是在 Android 上,则始终使用后台线程。
     *
     * 与ThreadMode.MAIN相反,如果在子线程发送事件,则直接在子线程处理事件;如果在主线程上发送事件,则先将事件入队列,然后通过线程池处理事件。
     */
    BACKGROUND,

    /**
     * Subscriber will be called in a separate thread. This is always independent from the posting thread and the
     * main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should
     * use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number
     * of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus
     * uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.
     *
     * 订阅者将在单独的线程中调用。 这始终独立于发布线程和主线程。 使用此模式发布事件从不等待订阅者方法。
     * 如果订阅者方法的执行可能需要一些时间,则应使用此模式,例如 用于网络访问。
     * 避免同时触发大量长时间运行的异步订阅者方法以限制并发线程数。
     * EventBus 使用线程池来有效地重用来自已完成的异步订阅者通知的线程。
     *
     * 与ThreadMode.MAIN_ORDERED相反,无论在哪个线程发送事件,都将事件加入到队列中,然后通过线程池执行事件
     */
    ASYNC
}

2.Subscribe注解

@Documented
@Retention(RetentionPolicy.RUNTIME)// 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Target({ElementType.METHOD})// 作用在方法上
public @interface Subscribe {
//    指定事件订阅方法所在的线程模式,也就是决定订阅方法是在哪个线程,默认是POSTING模式
    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).
     * 如果为 true,则将最近的粘性事件(通过 {@link EventBus#postSticky(Object)} 发布)传递给该订阅者(如果事件可用)。
     * 是否支持粘性事件
     */
    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;
}

3.SubscriberMethodInfo和Subscribe注解一一对应

public class SubscriberMethodInfo {
    final String methodName;
    final ThreadMode threadMode;
    final Class<?> eventType;
    final int priority;
    final boolean sticky;

    public SubscriberMethodInfo(String methodName, Class<?> eventType, ThreadMode threadMode,
                                int priority, boolean sticky) {
        this.methodName = methodName;
        this.threadMode = threadMode;
        this.eventType = eventType;
        this.priority = priority;
        this.sticky = sticky;
    }

    public SubscriberMethodInfo(String methodName, Class<?> eventType) {
        this(methodName, eventType, ThreadMode.POSTING, 0, false);
    }

    public SubscriberMethodInfo(String methodName, Class<?> eventType, ThreadMode threadMode) {
        this(methodName, eventType, threadMode, 0, false);
    }

}

4.SubscriberMethod和Subscribe注解一一对应

public class SubscriberMethod {
    final Method method;//反射里边的
    final ThreadMode threadMode;
    final Class<?> eventType;
    final int priority;
    final 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();
    }
}

5.Subscription订阅关系

final class Subscription {
    final Object subscriber;//实例
    final SubscriberMethod subscriberMethod;
    /**
     * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery
     * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions.
     */
    volatile boolean active;

    Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
        this.subscriber = subscriber;
        this.subscriberMethod = subscriberMethod;
        active = true;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Subscription) {
            Subscription otherSubscription = (Subscription) other;
            return subscriber == otherSubscription.subscriber
                    && subscriberMethod.equals(otherSubscription.subscriberMethod);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
    }
}

6.PendingPost

final class PendingPost {
    private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();

    Object event;
    Subscription subscription;
    PendingPost next;

    //构造函数
    private PendingPost(Object event, Subscription subscription) {
        this.event = event;
        this.subscription = subscription;
    }

    static PendingPost obtainPendingPost(Subscription subscription, Object event) {
        synchronized (pendingPostPool) {
            int size = pendingPostPool.size();
            if (size > 0) {
                PendingPost pendingPost = pendingPostPool.remove(size - 1);
                pendingPost.event = event;
                pendingPost.subscription = subscription;
                pendingPost.next = null;
                return pendingPost;
            }
        }
        return new PendingPost(event, subscription);
    }

    static void releasePendingPost(PendingPost pendingPost) {
        pendingPost.event = null;
        pendingPost.subscription = null;
        pendingPost.next = null;
        synchronized (pendingPostPool) {
            // Don't let the pool grow indefinitely
            if (pendingPostPool.size() < 10000) {
                pendingPostPool.add(pendingPost);
            }
        }
    }

}

7.PendingPostQueue

final class PendingPostQueue {
    private PendingPost head;
    private PendingPost tail;

    synchronized void enqueue(PendingPost pendingPost) {
        if (pendingPost == null) {
            throw new NullPointerException("null cannot be enqueued");
        }
        if (tail != null) {
            tail.next = pendingPost;
            tail = pendingPost;
        } else if (head == null) {
            head = tail = pendingPost;
        } else {
            throw new IllegalStateException("Head present, but no tail");
        }
        notifyAll();
    }

    synchronized PendingPost poll() {
        PendingPost pendingPost = head;
        if (head != null) {
            head = head.next;
            if (head == null) {
                tail = null;
            }
        }
        return pendingPost;
    }

    synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
        if (head == null) {
            wait(maxMillisToWait);
        }
        return poll();
    }

}

8.Poster

/**
 * Posts events.
 *
 * @author William Ferguson
 * ok
 */
interface Poster {

    /**
     * Enqueue an event to be posted for a particular subscription.
     *
     * @param subscription Subscription which will receive the event.
     * @param event        Event that will be posted to subscribers.
     */
    void enqueue(Subscription subscription, Object event);
}

9.HandlerPoster

/*
 * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.greenrobot.eventbus;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;

//mainThreadPoster为HandlerPoster, 具体分析下HandlerPoster
public class HandlerPoster extends Handler implements Poster {

    private final PendingPostQueue queue;
    private final int maxMillisInsideHandleMessage;//10 ms
    private final EventBus eventBus;
    private boolean handlerActive;

    protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        // 用subscription和event封装一个PendingPost对象
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            // 加入到队列中
            queue.enqueue(pendingPost);
            if (!handlerActive) {
                handlerActive = true;
                // sendMessage()发送处理事件的消息,handleMessage()方法将被执行,将子线程切换到主线程
                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对象
                        pendingPost = queue.poll();
                        if (pendingPost == null) {
                            handlerActive = false;
                            return;
                        }
                    }
                }
                //在主线程处理事件
                eventBus.invokeSubscriber(pendingPost);
                long timeInMethod = SystemClock.uptimeMillis() - started;
                //处理事件完了,大于10ms则重新取消息处理
                if (timeInMethod >= maxMillisInsideHandleMessage) {//又发了次消息
                    if (!sendMessage(obtainMessage())) {
                        throw new EventBusException("Could not send handler message");
                    }
                    rescheduled = true;
                    return;
                }
            }
        } finally {
            handlerActive = rescheduled;
        }
    }
}

10.BackgroundPoster

/**
 * Posts events in background.
 *
 * @author Markus
 * ok
 */
final class BackgroundPoster implements Runnable, Poster {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    private volatile boolean executorRunning;

    BackgroundPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        // 用subscription和event封装一个PendingPost对象
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            // 加入队列
            queue.enqueue(pendingPost);
            if (!executorRunning) {
                executorRunning = true;
                // 调用newCachedThreadPool线程池,执行任务 ???
                eventBus.getExecutorService().execute(this);
            }
        }
    }

    @Override
    public void run() {
        try {
            try {
                // 循环队列
                while (true) {
                    // 等待1秒,取出PendingPost对象
                    PendingPost pendingPost = queue.poll(1000);
                    if (pendingPost == null) {
                        synchronized (this) {
                            // Check again, this time in synchronized
                            pendingPost = queue.poll();
                            if (pendingPost == null) {
                                executorRunning = false;
                                return;
                            }
                        }
                    }
                    eventBus.invokeSubscriber(pendingPost);
                }
            } catch (InterruptedException e) {
                eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
            }
        } finally {
            executorRunning = false;
        }
    }

}

11.AsyncPoster

/**
 * Posts events in background.
 * 
 * @author Markus
 * ok
 */
class AsyncPoster implements Runnable, Poster {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    AsyncPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        queue.enqueue(pendingPost);
        eventBus.getExecutorService().execute(this);
    }

    @Override
    public void run() {
        PendingPost pendingPost = queue.poll();
        if(pendingPost == null) {
            throw new IllegalStateException("No pending post available");
        }
        eventBus.invokeSubscriber(pendingPost);
    }

}

12.MainThreadSupport

/**
 * Interface to the "main" thread, which can be whatever you like.
 * Typically on Android, Android's main thread is used.
 * ok
 */
public interface MainThreadSupport {

    boolean isMainThread();

    Poster createPoster(EventBus eventBus);

    class AndroidHandlerMainThreadSupport implements MainThreadSupport {

        private final Looper looper;//主线程looper

        public AndroidHandlerMainThreadSupport(Looper looper) {
            this.looper = looper;
        }

        @Override
        public boolean isMainThread() {
            return looper == Looper.myLooper();
        }

        @Override
        public Poster createPoster(EventBus eventBus) {
            return new HandlerPoster(eventBus, looper, 10);
        }
    }

}

13.SubscriberInfo

/** Base class for generated index classes created by annotation processing. */
//ok
public interface SubscriberInfo {
    Class<?> getSubscriberClass();

    SubscriberMethod[] getSubscriberMethods();

    SubscriberInfo getSuperSubscriberInfo();

    boolean shouldCheckSuperclass();
}

14.AbstractSubscriberInfo

/** Base class for generated subscriber meta info classes created by annotation processing. */
public abstract class AbstractSubscriberInfo implements SubscriberInfo {
    private final Class subscriberClass;
    private final Class<? extends SubscriberInfo> superSubscriberInfoClass;
    private final boolean shouldCheckSuperclass;

    protected AbstractSubscriberInfo(Class subscriberClass, Class<? extends SubscriberInfo> superSubscriberInfoClass,
                                     boolean shouldCheckSuperclass) {
        this.subscriberClass = subscriberClass;
        this.superSubscriberInfoClass = superSubscriberInfoClass;
        this.shouldCheckSuperclass = shouldCheckSuperclass;
    }

    @Override
    public Class getSubscriberClass() {
        return subscriberClass;
    }

    @Override
    public SubscriberInfo getSuperSubscriberInfo() {//??todo 干哈的
        if(superSubscriberInfoClass == null) {
            return null;
        }
        try {
            return superSubscriberInfoClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean shouldCheckSuperclass() {
        return shouldCheckSuperclass;
    }

    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType) {
        return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0, false);
    }

    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode) {
        return createSubscriberMethod(methodName, eventType, threadMode, 0, false);
    }

    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode,
                                                      int priority, boolean sticky) {
        try {
            Method method = subscriberClass.getDeclaredMethod(methodName, eventType);
            return new SubscriberMethod(method, eventType, threadMode, priority, sticky);
        } catch (NoSuchMethodException e) {
            throw new EventBusException("Could not find subscriber method in " + subscriberClass +
                    ". Maybe a missing ProGuard rule?", e);
        }
    }

}

15.SimpleSubscriberInfo

public class SimpleSubscriberInfo extends AbstractSubscriberInfo {

    private final SubscriberMethodInfo[] methodInfos;

    public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) {
        super(subscriberClass, null, shouldCheckSuperclass);
        this.methodInfos = methodInfos;
    }

    //通过methodInfos获取SubscriberMethod
    @Override
    public synchronized SubscriberMethod[] getSubscriberMethods() {
        int length = methodInfos.length;
        SubscriberMethod[] methods = new SubscriberMethod[length];
        for (int i = 0; i < length; i++) {
            SubscriberMethodInfo info = methodInfos[i];
            methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode,
                    info.priority, info.sticky);
        }
        return methods;
    }
}

16.SubscriberInfoIndex

public interface SubscriberInfoIndex {
    SubscriberInfo getSubscriberInfo(Class<?> subscriberClass);
}

17.SubscriberMethodFinder

class SubscriberMethodFinder {
    //region 参数
    /*
     * In newer class files, compilers may add methods. Those are called bridge or synthetic methods.
     * EventBus must ignore both. There modifiers are not public but defined in the Java class file format:
     * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6-200-A.1
     */
    private static final int BRIDGE = 0x40;
    private static final int SYNTHETIC = 0x1000;

    private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;
    //subscriberClass 方法
    private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
    private static final int POOL_SIZE = 4;
    //干哈的??
    private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];
    private final boolean strictMethodVerification;//严格方法检查,默认false,public, non-static, and non-abstract,一个参数
    private final boolean ignoreGeneratedIndex;//忽略生成的index,默认false
    //注解处理器生成的SubscriberInfoIndex
    private final List<SubscriberInfoIndex> subscriberInfoIndexes;
    //endregion

    //region ok 构造函数
    SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
                           boolean ignoreGeneratedIndex) {
        this.subscriberInfoIndexes = subscriberInfoIndexes;//注解处理器生成的SubscriberInfoIndex
        this.strictMethodVerification = strictMethodVerification;//false
        this.ignoreGeneratedIndex = ignoreGeneratedIndex;//false
    }
    //endregion

    static void clearCaches() {
        METHOD_CACHE.clear();
    }
    //endregion

    //region ok findSubscriberMethods
    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        //先从缓存里面读取,订阅者的 Class
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
        // ignoreGeneratedIndex属性表示是否忽略注解器生成的MyEventBusIndex。
        // ignoreGeneratedIndex的默认值为false,可以通过EventBusBuilder来设置它的值
        if (ignoreGeneratedIndex) {
            // 利用反射来获取订阅类中所有订阅方法信息
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            // 从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
            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;
        }
    }

    //region findUsingInfo
    //从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息 // 使用apt提前解析的订阅者信息
    private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        // FindState 涉及到 享元设计模式
        FindState findState = prepareFindState();
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
            //遍历subscriberInfoIndexes里的 SubscriberInfoIndex,
            //如果其getSubscriberInfo(findState.clazz)
            //不为null则返回得到的SubscriberInfo
            findState.subscriberInfo = getSubscriberInfo(findState);
            if (findState.subscriberInfo != null) {
                //得到所有的SubscriberMethod
                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();
        }
        // 释放 findState 享元模式
        return getMethodsAndRelease(findState);
    }
    //endregion

    private SubscriberInfo getSubscriberInfo(FindState findState) {
        if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
            //这个时候,clazz代表父类,getSuperSubscriberInfo得到父类的SubscriberInfo的class刚好是clazz
            //则直接返回
            SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
            if (findState.clazz == superclassInfo.getSubscriberClass()) {
                return superclassInfo;
            }
        }
        //遍历subscriberInfoIndexes里的 SubscriberInfoIndex,如果其getSubscriberInfo(findState.clazz)
        //不为null则返回得到的SubscriberInfo
        if (subscriberInfoIndexes != null) {
            for (SubscriberInfoIndex index : subscriberInfoIndexes) {
                SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
                if (info != null) {
                    return info;
                }
            }
        }
        return null;
    }

    //region ok getMethodsAndRelease prepareFindState clearCaches
    //享元模式本质就是将大量的相似的对象的公共的不会变化的部分抽象出来,作为静态变量,作为全局唯一的对象,让所有的对象共同使用这一组对象,达到节约内存的目的。
    private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
        List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
        findState.recycle();
        synchronized (FIND_STATE_POOL) {
            for (int i = 0; i < POOL_SIZE; i++) {
                if (FIND_STATE_POOL[i] == null) {
                    FIND_STATE_POOL[i] = findState;
                    break;
                }
            }
        }
        return subscriberMethods;
    }

    //从FindState[]数组缓存里取一个FindState
    private FindState prepareFindState() {
        synchronized (FIND_STATE_POOL) {
            for (int i = 0; i < POOL_SIZE; i++) {
                FindState state = FIND_STATE_POOL[i];
                if (state != null) {
                    FIND_STATE_POOL[i] = null;
                    return state;
                }
            }
        }
        return new FindState();
    }
    //endregion

    // 利用反射来获取订阅类中所有订阅方法信息
    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);
            }
            //出现异常的时候skipSuperClasses设置为true
            findState.skipSuperClasses = true;
        }
        // for 循环所有方法
        for (Method method : methods) {
            // 获取方法访问修饰符
            int modifiers = method.getModifiers();
            //  找到所有声明为 public 的方法,并且不是忽略的方法
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                Class<?>[] parameterTypes = method.getParameterTypes();// 获取参数的的 Class
                if (parameterTypes.length == 1) {// 只允许包含一个参数
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
                        // 获取事件的 Class ,也就是方法参数的 Class
                        Class<?> eventType = parameterTypes[0];
                        // 检测添加
                        if (findState.checkAdd(method, eventType)) {
                            // 获取 ThreadMode
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            // 往集合里面添加 SubscriberMethod ,解析方法注解所有的属性
                            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");
            }
        }
    }


    static class FindState {
        //region 参数
        //订阅方法集合,这里是最后返回的
        final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
        //eventtype对应的方法
        final Map<Class, Object> anyMethodByEventType = new HashMap<>();
        //methdkey对应的订阅者
        final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
        final StringBuilder methodKeyBuilder = new StringBuilder(128);

        //当前订阅者的类
        Class<?> subscriberClass;
        //当前查找的类
        Class<?> clazz;//父类,初始化的时候就是subscriberClass
        //是否跳过父类查找
        boolean skipSuperClasses;
        SubscriberInfo subscriberInfo;//订阅者信息
        //endregion

        //region initForSubscriber recycle
        void initForSubscriber(Class<?> subscriberClass) {
            this.subscriberClass = clazz = subscriberClass;
            skipSuperClasses = false;
            subscriberInfo = null;
        }

        void recycle() {
            subscriberMethods.clear();
            anyMethodByEventType.clear();
            subscriberClassByMethodKey.clear();
            methodKeyBuilder.setLength(0);
            subscriberClass = null;
            clazz = null;
            skipSuperClasses = false;
            subscriberInfo = null;
        }
        //endregion

        //region checkAdd()方法用来判断FindState中是否已经添加过将该事件类型为key的键值对,没添加过则返回true
        //处理两种情况
        //一.假如注册了3个方法,方法名不一样afun1 afun2 afun3,都添加
        //二.子类覆盖了父类的订阅方法,只保留子类的
        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.

            // 1.检查eventType是否已经注册过对应的方法(一般都没有)
            Object existing = anyMethodByEventType.put(eventType, method);
            if (existing == null) {
//                第一种是判断当前类中是否已经有这个EventType和对应的订阅方法,一般一个类不会有对同
//                一个EventType写多个方法,会直接返回true,进行保存。
                //如果没有,则返回true
                return true;
            } else {

                // 2. 如果已经有方法注册了这个eventType
//                但是如果出现了同一个类中同样的EventType写了多个方法,该如何处理?

                //a.1 假如注册了3个方法,方法名不一样afun1 afun2 afun3
                //a.7 afun3 的时候existing 对象不是method了
                //b.1 子类bfun_child,父类也注册了bfun_parent
                if (existing instanceof Method) {
                    //这里步骤的意义在于往subscriberClassByMethodKey map里加入第一个方法
                    //a.2 existing是以前的方法afun1
                    //b.2 传入以前的方法bfun_child
                    if (!checkAddWithMethodSignature((Method) existing, eventType)) {
                        // Paranoia check
                        throw new IllegalStateException();
                    }
                    // Put any non-Method object to "consume" the existing Method
                    //a.4 anyMethodByEventType eventType设置了个不是Method的对象
                    //b.4 anyMethodByEventType eventType设置了个不是Method的对象
                    anyMethodByEventType.put(eventType, this);
                }
                //a.5 传入现在的方法afun2
                //a.8 传入现在的方法afun3
                //b.5 传入现在的方法bfun_parent
                return checkAddWithMethodSignature(method, eventType);

            }
        }

        private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
            // 以[方法名>eventType]为Key
            methodKeyBuilder.setLength(0);
            methodKeyBuilder.append(method.getName());
            methodKeyBuilder.append('>').append(eventType.getName());

            String methodKey = methodKeyBuilder.toString();

            // 拿到新的订阅方法所属类
            Class<?> methodClass = method.getDeclaringClass();//定义的类,可能是父类
            Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);

            //a.3 传入以前的方法afun1,methodClassOld为null,并保存到了subscriberClassByMethodKey afun1->key,返回true
            //b.3 传入以前的方法bfun_child,methodClassOld为null,并保存到了subscriberClassByMethodKey bfun_child->key,返回true

            //a.6 传入现在的方法afun2,methodClassOld为null,并保存到了subscriberClassByMethodKey afun2->key,返回true
            //b.6 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类
            //a.8 传入现在的方法afun3,methodClassOld为null,并保存到了subscriberClassByMethodKey afun3->key,返回true
//            对于同一类中同样的EventType写了多个方法,因为方法名不同,所以[方法名>eventType]的Key不同,
//            methodClassOld会为null,直接返回 true。所以这种情况会将所有相同EventType的方法都进行保存。
//            对于子类重写父类方法的情况,则methodClassOld(即子类)不为null,并且methodClassOld也不是methodClass的父类,
//            所以会返回false。即对于子类重写父类订阅方法,只会保存子类的订阅方法,忽略父类的订阅方法。

//            isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。
            //b.7 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类
            //isAssignableFrom判断是否为某个类的父类
            if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
                // Only add if not already found in a sub class
                return true;
            } else {
//                这次根据 方法名>参数名进行完整校验,因为同一个类中同名同参的函数是不存在的,而同名不同参的在前一步已经被过滤了,
//                所以这里确保在一个类中不会重复注册.
//                但如果子类重写父类的方法的话,就会出现相同的methodKey。这时EventBus会做一次验证,
//                并保留子类的订阅信息。由于扫描是由子类向父类的顺序,故此时应当保留methodClassOld而忽略methodClass。如果代码上的注释 Revert the put
                //b.8 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类,subscriberClassByMethodKey保存子类的,返回false,不保存
                // Revert the put, old class is further down the class hierarchy
                subscriberClassByMethodKey.put(methodKey, methodClassOld);
                return false;
            }
        }
        //endregion

        //region moveToSuperclass
        void moveToSuperclass() {
            if (skipSuperClasses) {
                clazz = null;
            } else {
                clazz = clazz.getSuperclass();
                String clazzName = clazz.getName();
                // Skip system classes, this degrades performance.
                // Also we might avoid some ClassNotFoundException (see FAQ for background).
                if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") ||
                        clazzName.startsWith("android.") || clazzName.startsWith("androidx.")) {
                    clazz = null;
                }
            }
        }
        //endregion
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值