三方库-EventBus源码解析(一)

1,088 阅读15分钟

EventBus源码解析(一)

源码版本:

  • EventBus:3.3.1

导航:

使用

定义事件

class MessageEvent(val message: String)

事件Event)是普通的对象,没有任何特定要求。

订阅方法

@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEvent) {
    Toast.makeText(applicationContext, event.message, Toast.LENGTH_SHORT).show()
}

创建一个接收事件的方法onMessageEvent方法,使用注解@Subscribe进行标注,同时标记事件接收的线程主线程

注册与注销

override fun onStart() {
    super.onStart()
    EventBus.getDefault().register(this)
}

override fun onStop() {
    EventBus.getDefault().unregister(this)
    super.onStop()
}

在订阅者内调用EventBus.getDefault().register(this)方法进行注册,调用EventBus.getDefault().unregister(this)方法进行反注册

Android中,在ActivityFragment中,您通常应该根据它们的生命周期进行注册。对于大多数情况,onStart/onStop 工作正常:

发送事件

普通事件

EventBus.getDefault().post(MessageEvent("Hello everyone!"))

粘性事件

EventBus.getDefault().postSticky(MessageEvent("Hello everyone!"))

源码

Subscribe注解

Subscribe类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    // 线程模型,默认为POSTING(发布线程)。
    ThreadMode threadMode() default ThreadMode.POSTING;

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

    // 优先级
    int priority() default 0;
}

Subscribe注解类,其只能声明在方法上,其有3个可配置选项。

  • threadMode线程模型,默认为POSTING(发布线程)。
  • sticky,是否是粘性事件,默认为false
  • priority优先级,默认为0

ThreadMode类

public enum ThreadMode {
    POSTING,
    MAIN,
    MAIN_ORDERED,
    BACKGROUND,
    ASYNC
}

ThreadMode枚举类,为线程模型,一共有5种。

  • POSTING发布线程
  • MAIN主线程
  • MAIN_ORDERED主线程(有序)
  • BACKGROUND后台线程
  • POASYNCTING异步线程

这里只是简单介绍,详细介绍看后面的-EventBuspost

EventBus的创建

EventBus.getDefault()

EventBus --> getDefault方法

public class EventBus {
    static volatile EventBus defaultInstance;
    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
    
    // 获取默认的EventBus对象,单例模式。
    public static EventBus getDefault() {
        EventBus instance = defaultInstance;
        if (instance == null) {
            synchronized (EventBus.class) {
                instance = EventBus.defaultInstance;
                if (instance == null) {
                    // 调用无参构造方法,创建EventBus。
                    instance = EventBus.defaultInstance = new EventBus();
                }
            }
        }
        return instance;
    }
}

EventBus.getDefault()方法,使用单例模式创建EventBus对象,EventBus的创建看new EventBus()创建方式。

new EventBus()

EventBus --> 构造方法

public class EventBus {
    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
   
    public EventBus() {
        // 调用EventBusBuilder为参的构造方法,传入一个默认的EventBusBuilder对象。
        this(DEFAULT_BUILDER);
    }
    
	EventBus(EventBusBuilder builder) {
	// 后面介绍,看EventBus的初始化。
        ...
    }
}

new EventBus(),使用的是默认EventBusBuilder的配置,EventBusBuilder的创建看EventBus.builder()创建方式。

EventBus.builder()

EventBus --> builder方法

public static EventBusBuilder builder() {
    return new EventBusBuilder();
}

EventBus.builder()方法,创建EventBusBuilder并返回,接下来我们看一下EventBusBuilder类创建EventBus的方法。

installDefaultEventBus

EventBusBuilder --> installDefaultEventBus方法

// 安装默认的EventBus
public EventBus installDefaultEventBus() {
    synchronized (EventBus.class) {
        if (EventBus.defaultInstance != null) {
            throw new EventBusException("Default instance already exists." +
                    " It may be only set once before it's used the first time to ensure consistent behavior.");
        }
        // 调用build方法创建EventBus,并给默认实例赋值。
        EventBus.defaultInstance = build();
        // 返回默认实例。
        return EventBus.defaultInstance;
    }
}

installDefaultEventBus()方法,通过build创建EventBus对象,并赋值给EventBus.defaultInstance,并返回其实例

说明:

  1. installDefaultEventBus()方法,必须在第一次调用EventBus.getDefault()之前调用,否则抛异常。
  2. installDefaultEventBus()方法,只能调用一次,再次调用则抛异常。

build

EventBusBuilder --> build方法

// 基于当前配置构建一个EventBus。
public EventBus build() {
    return new EventBus(this);
}

build()方法,创建EventBus对象,并传入当前EventBusBuilder实例,我们先来看一下EventBusBuilder类,然后再来看一下EventBus的初始化。

小结

  1. EventBus可通过3种方式创建,EventBus.getDefault()new EventBus()EventBus.builder().build(),它们最终都是通过EventBus(EventBusBuilder)创建。

EventBusBuilder

EventBusBuilder构建者模式构建EventBus,其提供了全部可配置的方法,以及一些其它获取的方法,我们来分别看一下。

配置项

EventBusBuilder类

public class EventBusBuilder {
    // 默认线程池
    private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
    
    boolean logSubscriberExceptions = true;
    boolean logNoSubscriberMessages = true;
    boolean sendSubscriberExceptionEvent = true;
    boolean sendNoSubscriberEvent = true;
    boolean throwSubscriberException;
    boolean eventInheritance = true;
    boolean ignoreGeneratedIndex;
    boolean strictMethodVerification;
    ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
    List<Class<?>> skipMethodVerificationForClasses;
    List<SubscriberInfoIndex> subscriberInfoIndexes;
    Logger logger;
    MainThreadSupport mainThreadSupport;

    EventBusBuilder() {
    }

    // 调用订阅方法异常时,是否打印异常信息,默认为true。
    public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
        this.logSubscriberExceptions = logSubscriberExceptions;
        return this;
    }

    // 没有订阅者时,是否打印异常信息,默认为true。
    public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
        this.logNoSubscriberMessages = logNoSubscriberMessages;
        return this;
    }

    // 调用订阅方法异常时,是否发送SubscriberExceptionEvent事件,默认为true。
    public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
        this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
        return this;
    }

    // 没有订阅者时,是否发送NoSubscriberEvent事件,默认为true。
    public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
        this.sendNoSubscriberEvent = sendNoSubscriberEvent;
        return this;
    }

    // 调用订阅方法异常时,是否抛出SubscriberException异常,默认为false。
    public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
        this.throwSubscriberException = throwSubscriberException;
        return this;
    }

    // 事件是否有继承性,默认为true。
    public EventBusBuilder eventInheritance(boolean eventInheritance) {
        this.eventInheritance = eventInheritance;
        return this;
    }
    
    // 为EventBus提供一个自定义线程池,用于异步和后台事件传递。
    public EventBusBuilder executorService(ExecutorService executorService) {
        this.executorService = executorService;
        return this;
    }

    // 跳过方法签名验证(目前未使用)
    public EventBusBuilder skipMethodVerificationFor(Class<?> clazz) {
        if (skipMethodVerificationForClasses == null) {
            skipMethodVerificationForClasses = new ArrayList<>();
        }
        skipMethodVerificationForClasses.add(clazz);
        return this;
    }

    // 是否忽略注解处理器生成的索引,默认为false。
    public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) {
        this.ignoreGeneratedIndex = ignoreGeneratedIndex;
        return this;
    }

    // 是否严格验证订阅方法,默认为false。
    public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) {
        this.strictMethodVerification = strictMethodVerification;
        return this;
    }

    // 添加注解处理器生成的索引
    public EventBusBuilder addIndex(SubscriberInfoIndex index) {
        if (subscriberInfoIndexes == null) {
            subscriberInfoIndexes = new ArrayList<>();
        }
        subscriberInfoIndexes.add(index);
        return this;
    }
    
    // 设置日志处理者
    public EventBusBuilder logger(Logger logger) {
        this.logger = logger;
        return this;
    }
}

配置项默认值,为属性默认值

1、异常处理配置

配置项描述默认值
logSubscriberExceptions调用订阅方法异常时,是否打印异常信息true
sendSubscriberExceptionEvent调用订阅方法异常时,是否发送SubscriberExceptionEvent事件true
throwSubscriberException调用订阅方法异常时,是否抛出SubscriberException异常false
logNoSubscriberMessages没有订阅者时,是否打印异常信息true
sendSubscriberExceptionEvent没有订阅者时,是否发送NoSubscriberEvent事件true

2、注解处理器配置

配置项描述默认值
ignoreGeneratedIndex是否忽略注解处理器生成的索引false
addIndex添加注解处理器生成的索引

3、其它配置

配置项描述默认值
eventInheritance事件是否有继承性true
executorService(ExecutorService)EventBus提供一个自定义线程池,用于异步和后台事件传递。Executors.newCachedThreadPool()
strictMethodVerification是否严格验证订阅方法false
logger设置日志处理者
skipMethodVerificationFor(Class<?>)跳过方法验证(目前未使用

getLogger

EventBusBuilder --> getLogger方法

// 获取日志处理者
Logger getLogger() {
    if (logger != null) {
        return logger;
    } else {
        return Logger.Default.get();
    }
}

getLogger()方法,如果有调用logger()方法设置过Logger,则用设置过的Logger,否则用默认Logger.Default.get()Logger,我们来看一下Logger类。

Logger类

public interface Logger {

    void log(Level level, String msg);

    void log(Level level, String msg, Throwable th);

    class JavaLogger implements Logger {
        protected final java.util.logging.Logger logger;

        public JavaLogger(String tag) {
            logger = java.util.logging.Logger.getLogger(tag);
        }

        @Override
        public void log(Level level, String msg) {
            // TODO Replace logged method with caller method
            logger.log(level, msg);
        }

        @Override
        public void log(Level level, String msg, Throwable th) {
            // TODO Replace logged method with caller method
            logger.log(level, msg, th);
        }

    }

    class SystemOutLogger implements Logger {

        @Override
        public void log(Level level, String msg) {
            System.out.println("[" + level + "] " + msg);
        }

        @Override
        public void log(Level level, String msg, Throwable th) {
            System.out.println("[" + level + "] " + msg);
            th.printStackTrace(System.out);
        }

    }

    class Default {
        public static Logger get() {
	    // 判断AndroidComponents是否可用,如果可用则用AndroidComponents的logger。
            if (AndroidComponents.areAvailable()) {
                return AndroidComponents.get().logger;
            }

            return new SystemOutLogger();
        }
    }

}

Logger类,为日志处理者,是一个接口,它有两个log()方法,JavaLoggerSystemOutLogger为其实现类

Logger.Default.get()方法,通过AndroidComponents.areAvailable()方法,判断AndroidComponents是否可用,如果可用则用AndroidComponents实现类的logger,否则用SystemOutLogger,我们来看一下AndroidComponents类。

AndroidComponents类

public abstract class AndroidComponents {
    // AndroidComponents类实现者
    private static final AndroidComponents implementation;

    static {
        // 实现者实例,如果Android SDK可用,则创建AndroidComponents实现者实例并赋值给它,否则赋值为null。
        implementation = AndroidDependenciesDetector.isAndroidSDKAvailable()
            ? AndroidDependenciesDetector.instantiateAndroidComponents()
            : null;
    }

    // AndroidComponents是否可用
    public static boolean areAvailable() {
        return implementation != null;
    }

    // 获取AndroidComponents实现类实例
    public static AndroidComponents get() {
        return implementation;
    }

    public final Logger logger;
    public final MainThreadSupport defaultMainThreadSupport;

    // 创建AndroidComponents,需要Logger、MainThreadSupport。
    public AndroidComponents(Logger logger, MainThreadSupport defaultMainThreadSupport) {
        this.logger = logger;
        this.defaultMainThreadSupport = defaultMainThreadSupport;
    }
}

AndroidComponents类,为Android组件,它持有LoggerMainThreadSupport,以及含有areAvailable()get()两个静态方法。

implementation属性为AndroidComponents实现类实例,通过AndroidDependenciesDetector判断,如果Android SDK可用,则创建AndroidComponents实现类实例并赋值给它,否则赋值为null,我们来看一下AndroidDependenciesDetector类。

AndroidDependenciesDetector类

public class AndroidDependenciesDetector {

    // 判断Android SDK是否是可用的,其内部判断为Looper.getMainLooper()是否有值。
    public static boolean isAndroidSDKAvailable() {

        try {
            // 反射获取Looper类Class
            Class<?> looperClass = Class.forName("android.os.Looper");
            // 反射获取Looper类getMainLooper方法Method
            Method getMainLooper = looperClass.getDeclaredMethod("getMainLooper");
            // 反射获取Looper类getMainLooper方法返回值
            Object mainLooper = getMainLooper.invoke(null);
            // 判断Looper类getMainLooper方法返回值是否为空
            return mainLooper != null;
        }
        catch (ClassNotFoundException ignored) {}
        catch (NoSuchMethodException ignored) {}
        catch (IllegalAccessException ignored) {}
        catch (InvocationTargetException ignored) {}

        return false;
    }

    private static final String ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME = "org.greenrobot.eventbus.android.AndroidComponentsImpl";

    // 判断AndroidComponents是否是可用的,其内部判断为是否有AndroidComponentsImpl类。
    public static boolean areAndroidComponentsAvailable() {

        try {
            Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
            return true;
        }
        catch (ClassNotFoundException ex) {
            return false;
        }
    }

    // 创建AndroidComponents实现类,其内部为反射创建AndroidComponentsImpl类。
    public static AndroidComponents instantiateAndroidComponents() {

        try {
            Class<?> impl = Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
            return (AndroidComponents) impl.getConstructor().newInstance();
        }
        catch (Throwable ex) {
            return null;
        }
    }
}

AndroidDependenciesDetector类,它为Android依赖发现者,它含有以下3个静态方法

  • isAndroidSDKAvailable(),判断Android SDK是否是可用的,其内部判断为Looper.getMainLooper()是否有值。
  • areAndroidComponentsAvailable(),判断AndroidComponents是否是可用的,其内部判断为是否有AndroidComponentsImpl类。
  • instantiateAndroidComponents(),创建AndroidComponents实现类,其内部为反射创建AndroidComponentsImpl类。

说明:

  1. isAndroidSDKAvailable(),通过它可以判断是否是在Android平台。
  2. areAndroidComponentsAvailable(),通过它可以判断是否是只引用了eventbus-java库,未引用了eventbus库(说明:eventbus-java库为Java库,eventbus库为Android库,引用eventbus默认会引用eventbus-java)。

我们再来看一下AndroidComponentsImpl类。

AndroidComponentsImpl类

public class AndroidComponentsImpl extends AndroidComponents {

    public AndroidComponentsImpl() {
        super(new AndroidLogger("EventBus"), new DefaultAndroidMainThreadSupport());
    }
}

AndroidComponentsImpl类,它是AndroidComponents的实现类,其LoggerAndroidLogger,其MainThreadSupportDefaultAndroidMainThreadSupportAndroidLogger类,其内部使用Log进行打印,源码自行查看,我们接下来看一下DefaultAndroidMainThreadSupport类。

DefaultAndroidMainThreadSupport类

public class DefaultAndroidMainThreadSupport implements MainThreadSupport {

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

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

DefaultAndroidMainThreadSupport类,为默认的Android主线程支持类,其通过isMainThread()判断是否是在主线程,通过createPoster()创建主线程Poster,为HandlerPoster

说明:

  1. isMainThread()方法,用Looper.myLooper() == Looper.getMainLooper()比较的话,会浪费资源。因为Looper.myLooper()方法获取Looper,如果在新线程调用的话,ThreadLocal会创建ThreadLocalMap。建议改成用:Looper.getMainLooper().getThread() == Thread.currentThread()

getMainThreadSupport

EventBusBuilder --> getMainThreadSupport方法

// 获取MainThread支持
MainThreadSupport getMainThreadSupport() {
    if (mainThreadSupport != null) {
        // mainThreadSupport未使用
        return mainThreadSupport;
    } else if (AndroidComponents.areAvailable()) {
        // AndroidComponents可用,则获取到其MainThreadSupport,即DefaultAndroidMainThreadSupport。
        return AndroidComponents.get().defaultMainThreadSupport;
    } else {
        return null;
    }
}

getMainThreadSupport()方法,如果AndroidComponents可用,则获取到其(即AndroidComponentsImplMainThreadSupport,即DefaultAndroidMainThreadSupport

小结

  1. EventBusBuilder构建者模式构建EventBus,其提供了全部可配置的方法。
  2. getLogger()方法,如果是Android平台,则为AndroidLogger,否则为SystemOutLogger
  3. getMainThreadSupport()方法,如果是Android平台,则为DefaultAndroidMainThreadSupport,否则为null

EventBusBuilder相关的我们已经介绍完,接下来我们看一下EventBus的初始化。

EventBus的初始化

EventBus所有方式创建,最终都会走到EventBus(EventBusBuilder)构造方法,我们接下来看一下EventBus(EventBusBuilder)构造方法。

EventBus --> 构造方法

private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
private final Map<Object, List<Class<?>>> typesBySubscriber;
private final Map<Class<?>, Object> stickyEvents;

private final MainThreadSupport mainThreadSupport;
private final Poster mainThreadPoster;
private final BackgroundPoster backgroundPoster;
private final AsyncPoster asyncPoster;
private final SubscriberMethodFinder subscriberMethodFinder;
private final ExecutorService executorService;

private final boolean throwSubscriberException;
private final boolean logSubscriberExceptions;
private final boolean logNoSubscriberMessages;
private final boolean sendSubscriberExceptionEvent;
private final boolean sendNoSubscriberEvent;
private final boolean eventInheritance;

private final int indexCount;
private final Logger logger;

EventBus(EventBusBuilder builder) {
    // 日志处理者
    logger = builder.getLogger();

    // =============以下3个集合很重要==================
    // [事件 --> 该事件的订阅关系的List] 的Map。
    // 1.key:Event的Class,value:Subscription(持有订阅者对象、订阅方法的对象)的List。
    // 2.即通过它,方便通过Event事件,找到此事件所有的Subscription(持有订阅者对象、订阅方法的对象,方便反射调用)。
    // 3.举例:有一个Event为MessageEvent,它被A、B、C三个类进行了订阅,则它里面有一条数据,
    // key为MessageEvent的Class,value为有3条数据(A、B、C三个类的Subscription)的List。
    subscriptionsByEventType = new HashMap<>();
    // [订阅者 --> 该订阅者订阅的事件的List] 的Map。
    // 1.key:订阅者对象Object,value:Event的Class的List。
    // 2.即通过它,方便通过订阅者对象,找到其订阅的所有Event类型。
    // 3.举例:有2个Event为MessageEvent、SayHelloEvent,它被A类都进行了订阅,则它里面有一条数据,
    // key为A类对象,value为有2条数据(MessageEvent、SayHelloEvent两个类的Class)的List。
    typesBySubscriber = new HashMap<>();
    // [粘性事件 --> 粘性事件对象] 的Map。
    // 1.key:Event的Class,value:Event的对象。
    // 2.即通过它,方便通过Event(粘性事件)的Class,找到其(粘性事件)实例。
    stickyEvents = new ConcurrentHashMap<>();

    // =============以下在事件发送中很重要==================
    // 主线程支持,Android平台为DefaultAndroidMainThreadSupport,否则为null。
    mainThreadSupport = builder.getMainThreadSupport();
    // 主线程事件发送者,Android平台为HandlerPoster,否则为null。
    mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
    // Background事件发送者
    backgroundPoster = new BackgroundPoster(this);
    // 异步事件发送者
    asyncPoster = new AsyncPoster(this);

    // =============以下为获取EventBusBuilder的配置==================
    // 添加注解处理器生成的索引SubscriberInfoIndex的个数
    indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
    // 订阅方法查找对象(后面会详细介绍此类及其构造参数)
    subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
            builder.strictMethodVerification, builder.ignoreGeneratedIndex);
    // 调用订阅方法异常时,是否打印异常信息,默认为true。
    logSubscriberExceptions = builder.logSubscriberExceptions;
    // 没有订阅者时,是否打印异常信息,默认为true。
    logNoSubscriberMessages = builder.logNoSubscriberMessages;
    // 调用订阅方法异常时,是否发送SubscriberExceptionEvent事件,默认为true。
    sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
    // 没有订阅者时,是否发送NoSubscriberEvent事件,默认为true。
    sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
    // 调用订阅方法异常时,是否抛出SubscriberException异常,默认为false。
    throwSubscriberException = builder.throwSubscriberException;
    // 事件是否有继承性,默认为true。
    eventInheritance = builder.eventInheritance;
    // 线程池,用于异步和后台事件传递,默认为Executors.newCachedThreadPool()。
    executorService = builder.executorService;
}

小结

  1. EventBus初始化,创建了3个很重要的集合,subscriptionsByEventTypetypesBySubscriberstickyEvents,详细解释看上面注释。
  2. 创建了3个PostermainThreadPoster(即HandlerPoster)、backgroundPosterasyncPoster,详细介绍看后面的-Poster
  3. 获取EventBusBuilder的配置,并记录。
  4. 创建SubscriberMethodFinder,用于查找订阅方法,详细介绍看后面的-SubscriberMethodFinder

EventBus的注册

EventBus --> register()

public void register(Object subscriber) {
    if (AndroidDependenciesDetector.isAndroidSDKAvailable() && !AndroidDependenciesDetector.areAndroidComponentsAvailable()) {
        // 是android平台但是没依赖eventbus(Android)库,则抛出异常。
        throw new RuntimeException("It looks like you are using EventBus on Android, " +
                "make sure to add the \"eventbus\" Android library to your dependencies.");
    }
    // 1、获取到订阅者的Class对象。
    Class<?> subscriberClass = subscriber.getClass();
    // 2、通过subscriberMethodFinder对象找到该订阅者的所有订阅方法。
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    // 3、同步,保证线程安全。
    synchronized (this) {
        // 4、遍历集合进行订阅
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            // 5、订阅,传入订阅者对象、该订阅者的订阅方法对象。
            subscribe(subscriber, subscriberMethod);
        }
    }
}

register()方法,为注册订阅者方法,通过subscriberMethodFinder找到该订阅者所有订阅方法,然后进行遍历依次订阅SubscriberMethodFinder相关我们单独介绍(看后面的-SubscriberMethodFinder),我们先来看一下SubscriberMethod类。

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;

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

SubscriberMethod类,为订阅方法信息相关类,它记录了订阅方法上,Subscribe注解的信息、参数信息、以及反射方法Method(方便后续反射调用)。

在看subscribe()方法前,我们先来看一下Subscription类,其在subscribe()方法(稍后介绍)内使用。

Subscription类

final class Subscription {
    // 订阅者对象
    final Object subscriber;
    // 订阅方法
    final SubscriberMethod subscriberMethod;
    // 是否是活跃的
    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();
    }
}

Subscription类,为订阅者对象订阅方法封装类,方便后续反射调用订阅者对象订阅方法

我们继续来看一下subscribe()方法。

EventBus --> subscribe()

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    // 6、获取订阅方法的事件类型
    Class<?> eventType = subscriberMethod.eventType;
    // 7、封装Subscription对象(之后会将newSubscription添加到subscriptionsByEventType中)。
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    // 8、通过事件类型获取该事件的Subscription集合(之后会将newSubscription添加到subscriptions中)。
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions == null) {
        // 9、集合为空,说明该事件为第一次订阅,则创建集合,并把当前Event类型存入subscriptionsByEventType中。
        subscriptions = new CopyOnWriteArrayList<>();
        subscriptionsByEventType.put(eventType, subscriptions);
    } else {
        // 10、集合不为空,说明该事件已经被订阅过,则判断该订阅者是否有重复订阅的现象。
        if (subscriptions.contains(newSubscription)) {
            // 11、包含,则说明是重复订阅,此方法只有被register()方法调用,所以说明是重复注册,则抛出异常。
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                    + eventType);
        }
    }

    // 12、遍历该事件的所有订阅者,按照优先级进行插入。
    int size = subscriptions.size();
    // 13、i <= size,size最少为0,所以至少会执行一次for循环。
    for (int i = 0; i <= size; i++) {
        // 说明:
        // 1. i == size,则说明是最后一个。
        // 2. subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority,说明新的优先级高于当前的优先级。
        // 14、如果是最后一个,或者新的优先级高于当前的优先级,则添加到当前位置,即当前位置后移,整体从高到低排序。
        if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
            subscriptions.add(i, newSubscription);
            break;
        }
    }

    // 15、获取该订阅者订阅的事件的集合(之后会将eventType添加到subscribedEvents中)。
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
        // 16、集合为空,则说明是第一次添加订阅者,则创建集合,并把当前订阅者存入typesBySubscriber中。
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    // 17、将事件加入到该订阅者订阅的事件的集合中
    subscribedEvents.add(eventType);

    // 18、判断该订阅方法是否是粘性事件,如果是粘性事件,则注册时就会通知事件,因为发送粘性事件不管之前注册还是之后注册都会通知。
    if (subscriberMethod.sticky) {
        // 19、是粘性事件,则进行通知订阅方法。
        if (eventInheritance) { // eventInheritance:事件是否有继承性,默认为true。
            // 20、事件有继承性,则通知所有已发送粘性事件符合是其自己或者其子类的事件。
            // 21、获取所有已发送粘性事件,遍历判断是否符合是其自己或者其子类的事件。
            Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry<Class<?>, Object> entry : entries) {
                Class<?> candidateEventType = entry.getKey();
                if (eventType.isAssignableFrom(candidateEventType)) {
                    // 22、符合是其自己或者其子类的事件,subscriptions则进行通知。
                    Object stickyEvent = entry.getValue();
                    // 23、调用checkPostStickyEventToSubscription方法进行检查发送。
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
            // 24、事件没有继承性,则通知所有已发送粘性事件符合是其自己的事件。
            Object stickyEvent = stickyEvents.get(eventType);
            // 25、调用checkPostStickyEventToSubscription方法进行检查发送,stickyEvent有可能为null,因为可能之前没发送过此类事件的粘性事件。
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}

subscribe()方法,为订阅方法,其主要维护subscriptionsByEventTypetypesBySubscriber数据,并处理粘性方法,如果是粘性方法则调用checkPostStickyEventToSubscription()方法进行检查发送

说明:

  1. 步骤6-14,为维护subscriptionsByEventType集合数据。步骤14,则会导致该事件所有Subscription,按订阅方法优先级高到低排序。
  2. 步骤15-17,为维护typesBySubscriber集合数据。
  3. 步骤18-25,为判断是否是粘性方法,如果则再判断事件是否有继承性,找到其对应的事件对象,最后调用checkPostStickyEventToSubscription()方法进行检查发送,如检测成功则会通知订阅方法的。
  4. eventInheritance事件是否有继承性,默认为true,即会接收已经发送粘性事件其自己或者其子类的事件。
  5. 如果已经发送很多粘性事件,则遍历所有事件,所以会因有大量粘性事件效率低下

接下来,我们继续来看一下checkPostStickyEventToSubscription()方法。

EventBus --> checkPostStickyEventToSubscription()

private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
    if (stickyEvent != null) {
        // 26、如果粘性事件不为空,则进行发送粘性事件到订阅方法,并传入是否是在主线程发送。
        postToSubscription(newSubscription, stickyEvent, isMainThread());
    }
}

checkPostStickyEventToSubscription()方法,为检查发送粘性事件到订阅方法的方法,如果粘性事件不为空,则进行发送,并传入是否是在主线程发送,后面postToSubscription()就是我们的发送流程,详细介绍看后面的-EventBuspost

EventBus --> isMainThread()

private boolean isMainThread() {
    return mainThreadSupport == null || mainThreadSupport.isMainThread();
}

isMainThread()方法,为检查当前线程是否是在主线程的方法。

说明:

  1. 如果不是Android平台则始终为true,如果是Android平台则通过mainThreadSupport.isMainThread()判断是否是在主线程

小结

  1. EventBus注册,传入订阅者对象,通过反射获取到订阅者Class对象。
  2. 通过SubscriberMethodFinder获取订阅者中所有订阅方法集合。
  3. 遍历上面获取的集合,将订阅者事件进行包装绑定Subscription
  4. 维护subscriptionsByEventTypetypesBySubscriber集合数据,将Subscription添加到subscriptionsByEventType当前eventType(从订阅方法中获取)的List中,将eventType添加到typesBySubscriber当前订阅者List中。
  5. 并判断此订阅方法是否是粘性方法,如果是粘性方法,并且之前已经发送过此粘性事件,则进行发送粘性事件到此订阅方法

总结

以上就是EventBus源码的第一部分第二部分请看EventBus源码解析(二)。之后会出其它三方库源码系列,请及时关注。如果你有什么问题,大家评论区见!

最后推荐一下我的网站,开发者的技术博客: devbolg.cn ,目前包含android相关的技术,之后会面向全部开发者,欢迎大家来体验!