EventBus3 使用以及源码解析

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iamfuturetoo/article/details/79591626

EventBus是GreenRobot使用发布/订阅模式进行松耦合的框架。

官网中对EventBus的事件传递图如下:


EventBus的简单使用可以根据官网入门教程进行学习。

EventBus3基本使用

添加依赖:

implementation 'org.greenrobot:eventbus:3.1.1'

1.定义事件MsgEvent,事件实际是POJO。

package future.cn.demo;


public class MsgEvent {
    public final String message;

    public MsgEvent(String message) {
        this.message = message;
    }
}

2.定义订阅方法(即事件的回调方法),并注册订阅者。

package future.cn.demo;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MsgEvent event){
        Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

定义订阅回调方法,方法名称在EventBus3中是可以随意定义的。在定义的方法添加@Subscribe注解。

注册订阅者则通过

EventBus.getDefault().register(this);

在跳转的SecondActivity中onDestroy方法发送事件,即在关闭SecondActivity时进行事件传送。

package future.cn.demo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

import org.greenrobot.eventbus.EventBus;


public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().post(new MsgEvent("hello world"));
    }
}

返回到MainActivity的时候可以接收到发送过来的事件。

处理线程

EventBus发送事件的线程和处理事件的线程可以不同。EventBus中通过ThreadMode进行定义在哪个线程调用订阅方法。

ThreadMode是一个枚举类型,定义了五个枚举实例。现在分别对其进行说明。

1.POSTING

这也是默认的线程模式,事件传送是同步的进行的,而且一经post所有的订阅者会立即回调。这种模式也表明不需要切换线程,只适用于简单任务,短时即可完成。 如果post线程是主线程的话,不应该做耗时任务,防止阻塞线程。

2.MAIN

订阅者会在主线程被调用。如果Post 线程是主线程的话,事件处理方法则会直接被调用。事件处理方法不能做耗时任务,防止阻塞主线程。

3.MAIN_ORDRERED
这种模式,订阅者会在Android主线程被调用(不能处理耗时任务),事件会被加入队列用于后面传送到订阅者。如果有订阅者线程模式为MAIN和MAIN_OREDERED,则post事件之后,总是MAIN模式的订阅者事件处理方法先被调用,因为MAIN_ORDERED模式的订阅方法会被加入队列
4.BACKGROUND

订阅者会在后台线程被调用,如果posting线程不是主线程,则事件处理方法会在posting线程直接被调用,如果posting线程是主线程,则EventBus会使用一个单独的后台线程按顺序发送所有事件,事件处理应该很快结束防止阻塞后台线程。

5.ASYNC

事件处理方法在不同线程被调用。通常独立于posting线程以及主线程。这种模式下发送事件不会等待事件处理方法。通常此模式用于事件处理方法需要做耗时操作。EventBus使用线程池进行线程复用。

粘性事件

EventBus支持粘性事件,即在发布之后订阅也可以收到的事件。EventBus将最后的粘性事件保存在内存中。

发送粘性事件:

EventBus.getDefault().postSticky(new MsgEvent("hello activity"));

在register之前post粘性事件,在register过程中会所有sticky为true的订阅者都会收到粘性事件。

此外,还可以通过显式获取粘性事件

EventBus.getDefault().getStickyEvent(MsgEvent.class);

在处理完粘性事件后需要将其移除,以防后续订阅者会收到此粘性事件。

EventBus.getDefault().removeStickyEvent(MsgEvent.class);

源码解析

1.首先看register方法:

public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }
register方法中首先获取订阅者的Class对象,在第3行中获取订阅者方法列表,通过方法
subscriberMethodFinder.findSubscriberMethods(subscriberClass);

进入findSubscriberMethods,首先通过METHOD_CACHE获取subscriberMethods,初次进去应该为空。

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }

        if (ignoreGeneratedIndex) {
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            subscriberMethods = findUsingInfo(subscriberClass);
        }
        if (subscriberMethods.isEmpty()) {
            throw new EventBusException("Subscriber " + subscriberClass
                    + " and its super classes have no public methods with the @Subscribe annotation");
        } else {
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        }
    }

第7行判断ignoreGeneratedIndex,默认为false,在创建EventBus实例的时候通过EventBusBuilder设置。此处为false调用findUsingInfo。

private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();//创建FindState实例,或者从FindState池中获取一个实例
        findState.initForSubscriber(subscriberClass);//初始化FindState
        while (findState.clazz != null) {//clazz在初始化时赋值为subscriberClass,不为空。
            findState.subscriberInfo = getSubscriberInfo(findState);//获取subscriberInfo
            if (findState.subscriberInfo != null) {
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                for (SubscriberMethod subscriberMethod : array) {
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
                findUsingReflectionInSingleClass(findState);
            }
            findState.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }

在第5行时,通过getSubdcriberInfo获取subscriberInfo

private SubscriberInfo getSubscriberInfo(FindState findState) {
        if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
            SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
            if (findState.clazz == superclassInfo.getSubscriberClass()) {
                return superclassInfo;
            }
        }
        if (subscriberInfoIndexes != null) {
            for (SubscriberInfoIndex index : subscriberInfoIndexes) {
                SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
                if (info != null) {
                    return info;
                }
            }
        }
        return null;
    }

很显然在第二行中findState.subscriberInfo为空,因此会走到8行,判断subscriberInfoIndexes,subscriberInfoIndexes在EventBusBuilder中进行的初始化

public EventBusBuilder addIndex(SubscriberInfoIndex index) {
        if (subscriberInfoIndexes == null) {
            subscriberInfoIndexes = new ArrayList<>();
        }
        subscriberInfoIndexes.add(index);
        return this;
    }

因此这个subscriberInfoIndexes为空(这个地方后面再讲,与索引加速有关),因此会走findUsingReflectionInSingleClass方法,从方法名可以看出是通过反射进行查找。进入findUsingReflectionInSingleClass查看细节。

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
            methods = findState.clazz.getMethods();
            findState.skipSuperClasses = true;
        }
        for (Method method : methods) {
            int modifiers = method.getModifiers();
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length == 1) {
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
                        Class<?> eventType = parameterTypes[0];
                        if (findState.checkAdd(method, eventType)) {
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                    String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                    throw new EventBusException("@Subscribe method " + methodName +
                            "must have exactly 1 parameter but has " + parameterTypes.length);
                }
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                throw new EventBusException(methodName +
                        " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
            }
        }
    }

SubscriberMethod是对订阅者回调方法的封装,在for循环中通过反射获取订阅者方法,最后将SubscriberMethod添加到subscriberMethods容器中。再回到register方法中,将获取到的subscriberMethods通过循环遍历调用subscribe方法。

public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);//获取subscriberMethods
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);//循环调用subscribe方法
            }
        }
    }

    // Must be called in synchronized block
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        Class<?> eventType = subscriberMethod.eventType;//自定义MsgEvent的Class对象
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);//Subscription是对subscriber和subscriberMethod的封装
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);//通过Map容器将事件类型与对应的订阅者和订阅方法对应起来,以便与后面post的时候进行查找
        } else {
            if (subscriptions.contains(newSubscription)) {
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }

        int size = subscriptions.size();
        for (int i = 0; i <= size; i++) {
            if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
                subscriptions.add(i, newSubscription);
                break;
            }
        }//根据优先级将subscriberMethod放入

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

        if (subscriberMethod.sticky) {//在注册过程中,对已经post的粘性事件发送给订阅者。
            if (eventInheritance) {
                // Existing sticky events of all subclasses of eventType have to be considered.
                // Note: Iterating over all events may be inefficient with lots of sticky events,
                // thus data structure should be changed to allow a more efficient lookup
                // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
                Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
                for (Map.Entry<Class<?>, Object> entry : entries) {
                    Class<?> candidateEventType = entry.getKey();
                    if (eventType.isAssignableFrom(candidateEventType)) {
                        Object stickyEvent = entry.getValue();
                        checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                    }
                }
            } else {
                Object stickyEvent = stickyEvents.get(eventType);
                checkPostStickyEventToSubscription(newSubscription, stickyEvent);
            }
        }
    }
从上面代码可以看出,除了将订阅者信息进行保存,还处理了粘性事件,粘性事件被暂时保存在Map中,具体后面分析。

2.接下来看post方法

public void post(Object event) {
        PostingThreadState postingState = currentPostingThreadState.get();
        List<Object> eventQueue = postingState.eventQueue;
        eventQueue.add(event);

        if (!postingState.isPosting) {
            postingState.isMainThread = isMainThread();
            postingState.isPosting = true;
            if (postingState.canceled) {
                throw new EventBusException("Internal error. Abort state was not reset");
            }
            try {
                while (!eventQueue.isEmpty()) {
                    postSingleEvent(eventQueue.remove(0), postingState);
                }
            } finally {
                postingState.isPosting = false;
                postingState.isMainThread = false;
            }
        }
    }

currentPostingThreadState是一个ThreadLocal变量,初始值通过initialValue创建。

private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
        @Override
        protected PostingThreadState initialValue() {
            return new PostingThreadState();
        }
    };

post方法最后调用postSingleEvent()方法。

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
        Class<?> eventClass = event.getClass();
        boolean subscriptionFound = false;
        if (eventInheritance) {
            List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
            int countTypes = eventTypes.size();
            for (int h = 0; h < countTypes; h++) {
                Class<?> clazz = eventTypes.get(h);
                subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
            }
        } else {
            subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
        }
        if (!subscriptionFound) {
            if (logNoSubscriberMessages) {
                logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
            }
            if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
                    eventClass != SubscriberExceptionEvent.class) {
                post(new NoSubscriberEvent(this, event));
            }
        }
    }

第4行中eventInheritance默认为true。因此会去调用lookupAllEventTypes。进入lookupAllEventTypes

private static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {
        synchronized (eventTypesCache) {
            List<Class<?>> eventTypes = eventTypesCache.get(eventClass);
            if (eventTypes == null) {
                eventTypes = new ArrayList<>();
                Class<?> clazz = eventClass;
                while (clazz != null) {
                    eventTypes.add(clazz);
                    addInterfaces(eventTypes, clazz.getInterfaces());
                    clazz = clazz.getSuperclass();
                }
                eventTypesCache.put(eventClass, eventTypes);
            }
            return eventTypes;
        }
    }
通过循环查找继承树,将所有事件类型(比如自定义的MsgEvent类)全部找到,包括事件类型的父类,一直到Object类。

获取到EventTypes之后,通过循环调postSingleEventForEventType,将事件发送出去。

private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
        CopyOnWriteArrayList<Subscription> subscriptions;
        synchronized (this) {
            subscriptions = subscriptionsByEventType.get(eventClass);
        }
        if (subscriptions != null && !subscriptions.isEmpty()) {
            for (Subscription subscription : subscriptions) {
                postingState.event = event;
                postingState.subscription = subscription;
                boolean aborted = false;
                try {
                    postToSubscription(subscription, event, postingState.isMainThread);
                    aborted = postingState.canceled;
                } finally {
                    postingState.event = null;
                    postingState.subscription = null;
                    postingState.canceled = false;
                }
                if (aborted) {
                    break;
                }
            }
            return true;
        }
        return false;
    }

获取了注册的订阅者信息之后调用postToSubscription方法。进入postToSubscription方法

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
            case POSTING:
                invokeSubscriber(subscription, event);//通过方法名可以看出是调用订阅者方法,跟post方法在同一个线程。
                break;
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);//如果当前是主线程,则直接调用
                } else {
                    mainThreadPoster.enqueue(subscription, event);//如果post不在主线程,则先添加到队列
                }
                break;
            case MAIN_ORDERED:
                if (mainThreadPoster != null) {
                    mainThreadPoster.enqueue(subscription, event);
                } else {
                    // temporary: technically not correct as poster not decoupled from subscriber
                    invokeSubscriber(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }

下面逐个分析,posting就不说了,直接在posting线程进行调用。

(1).MAIN模式下,如果posting线程是主线程,则直接调用。如果不是主线程则通过

mainThreadPoster.enqueue(subscription, event);

进入enqueue方法,此方法实现在HandlerPost,HandlerPost是一个Handler,此类中内部维护者一个队列。

public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!handlerActive) {
                handlerActive = true;
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
            }
        }
    }

先将事件加入队列,然后通过发送消息到HandlerPost所在线程进行处理即主线程。

@Override
    public void handleMessage(Message msg) {
        boolean rescheduled = false;
        try {
            long started = SystemClock.uptimeMillis();
            while (true) {
                PendingPost pendingPost = queue.poll();
                if (pendingPost == null) {
                    synchronized (this) {
                        // Check again, this time in synchronized
                        pendingPost = queue.poll();
                        if (pendingPost == null) {
                            handlerActive = false;
                            return;
                        }
                    }
                }
                eventBus.invokeSubscriber(pendingPost);//调用订阅方法
                long timeInMethod = SystemClock.uptimeMillis() - started;
                if (timeInMethod >= maxMillisInsideHandleMessage) {
                    if (!sendMessage(obtainMessage())) {
                        throw new EventBusException("Could not send handler message");
                    }
                    rescheduled = true;
                    return;
                }
            }
        } finally {
            handlerActive = rescheduled;
        }
    }

(2).BACKGROUND模式下,如果post不在主线程,则直接调用订阅者方法。如果在主线程,则通过executorService开启一个新线程,等待一秒之后在进行调用订阅者方法。具体代码见BackgroundPoster。

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

    @Override
    public void run() {
        try {
            try {
                while (true) {
                    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;
        }
    }

(3).ASYNC模式下,直接开启另外的线程进行调用订阅者方法。

3.post粘性事件

粘性事件会保存在Map中,同时通过post方法将此事件传递出去。粘性事件可以通过显式获取,如果粘性事件在register之前post,在register过程中,会将粘性事件post出去。这里有两种情况:1.如果粘性事件在register之前post,那么如果订阅方法属性sticky为false,则是不能收到粘性事件的。2.如果在register之后调用postSticky,不管是否sticky=true,都可以收到。根据源码可以看出,postSticky方法里面调用了post方法。

4.索引加速

最后一部分是索引加速,前面在讲解获取订阅者方法的时候是通过反射获取的,运行时通过反射获取效率是很低的。因此EventBus3 增加了一部分索引加速。这里要用到编译时注解。

在build.gradle中需要添加如下配置

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ eventBusIndex : 'cn.future.MyEventBusIndex' ]
            }
        }
    }
}
 
dependencies {
    compile 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}

经过build之后,在build/generated/source/apt/debug/cn/future下生成文件MyEventBusIndex,代码如下:

package cn.future;

import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberMethodInfo;
import org.greenrobot.eventbus.meta.SubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberInfoIndex;

import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Map;

/** This class is generated by EventBus, do not edit. */
public class MyEventBusIndex implements SubscriberInfoIndex {
    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();

        putIndex(new SimpleSubscriberInfo(future.cn.demo.SecondActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent", future.cn.demo.MsgEvent.class, ThreadMode.MAIN, 0, true),
        }));

        putIndex(new SimpleSubscriberInfo(future.cn.demo.MainActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent2", future.cn.demo.MsgEvent.class, ThreadMode.ASYNC, 0, true),
            new SubscriberMethodInfo("onEvent", future.cn.demo.MsgEvent.class, ThreadMode.MAIN),
        }));

    }

    private static void putIndex(SubscriberInfo info) {
        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
    }

    @Override
    public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
        if (info != null) {
            return info;
        } else {
            return null;
        }
    }
}

此类中,在第一次加载MyEventBusIndex的时候将SubscriberInfo保存在一个静态Map中。通过以下方法将自定义Index加进去:

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// Now the default instance uses the given index. Use it like this:
EventBus eventBus = EventBus.getDefault();
此方法是将自定义Index加入默认的EventBus实例中。

因此在有索引的情况下:

private SubscriberInfo getSubscriberInfo(FindState findState) {
        if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
            SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
            if (findState.clazz == superclassInfo.getSubscriberClass()) {
                return superclassInfo;
            }
        }
        if (subscriberInfoIndexes != null) {
            for (SubscriberInfoIndex index : subscriberInfoIndexes) {
                SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
                if (info != null) {
                    return info;
                }
            }
        }
        return null;
    }
实际是通过获取静态HashMap中的SubscriberInfo,速度当然比反射要快。
展开阅读全文

没有更多推荐了,返回首页