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

EventBus源码解析(一)

源码版本:

  • EventBus:3.3.1

导航:

  • 三方库-EventBus源码解析(一)
  • 三方库-EventBus源码解析(二)
  • 更多的文章看这里:主页

使用

定义事件

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> skipMethodVerificationForClasses;
    List 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,其MainThreadSupportDefaultAndroidMainThreadSupport
AndroidLogger类,其内部使用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, CopyOnWriteArrayList> subscriptionsByEventType;
private final Map>> typesBySubscriber;
private final Map, 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 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 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> 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, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry, 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相关的技术,之后会面向全部开发者,欢迎大家来体验!

你可能感兴趣的:(三方库-EventBus源码解析(一))