EventBus源码解析

开始
  • EventBus的基本用法, 下面代码通过EventBus在两个Activity传递数据(当然也可以使用其他方法传递数据)这里只是作为演示用
public class FirstActivity extends BaseActivity {

    private TextView mTv;
    private static final String TAG = "FirstActivity";

    @Override
    protected void initView() {
        setContentView(R.layout.activity_first);
        mTv = findViewById(R.id.tv);
    }

    /**
     * 必须要是public、void并且有且只有一个参数,粘性表示当一个粘性消息已经发送了再注册还能再接受到该消息
     * @param msg 接受到的消息对象,可以任意
     */
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onReceiveEvent(Message msg) {
        Log.d(TAG, "onReceiveEvent: currentThread is " + Thread.currentThread());
        mTv.setText((String)msg.obj);
    }


    public void subscribe(View view) {
        EventBus.getDefault().register(this);
    }

    public void unSubscribe(View view) {
        EventBus.getDefault().unregister(this);
    }

    public void jump(View view) {
        startActivity(new Intent(this, SecondActivity.class));
    }
}
public class SecondActivity extends BaseActivity {

    @Override
    protected void initView() {
        setContentView(R.layout.activity_second);
    }

    public void sendStickyMsg(View view) {
        Message msg = Message.obtain();
        msg.obj = "我是第二个Activity通过发送消息带回来的数据";
        EventBus.getDefault().post(msg);
    }

    public void sendMsg(View view) {
        Message msg = Message.obtain();
        msg.obj = "我是第二个Activity通过发送粘性消息带回来的数据";
        EventBus.getDefault().postSticky(msg);
    }
}
源码分析
1. 从EventBus.getDefault()说起,这是一个典型的DLC单例模式(也可以使用builder创建一个EventBus实例)
// EventBus.java
public static EventBus getDefault() {
    if (defaultInstance == null) {
        synchronized (EventBus.class) {
            if (defaultInstance == null) {
                defaultInstance = new EventBus();
            }
        }
    }
    return defaultInstance;
}
// 接着看看构造方法
public EventBus() {
    this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
    logger = builder.getLogger(); // 1
    // key是事件类型,value是List<Subscription>
    subscriptionsByEventType = new HashMap<>();
    // key是订阅者,List<事件类型>,该对象存在的目的便于解除注册时删除
    typesBySubscriber = new HashMap<>();
    // 保存着所有的粘性事件
    stickyEvents = new ConcurrentHashMap<>();
    mainThreadSupport = builder.getMainThreadSupport(); // 2
    mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null; // 后面用到会说
    backgroundPoster = new BackgroundPoster(this); // 后面用到会说
    asyncPoster = new AsyncPoster(this); // 后面用到会说
    indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0; // 索引的数量,如果有索引的话
    subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
            builder.strictMethodVerification, builder.ignoreGeneratedIndex); // 3
    logSubscriberExceptions = builder.logSubscriberExceptions; // true
    logNoSubscriberMessages = builder.logNoSubscriberMessages; // true
    sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent; // true
    sendNoSubscriberEvent = builder.sendNoSubscriberEvent; // true
    throwSubscriberException = builder.throwSubscriberException; // false
    eventInheritance = builder.eventInheritance; // true 是否允许事件继承
    executorService = builder.executorService; // Executors.newCachedThreadPool()
}

关于索引,我们可以调用EventBusBuilder.addIndex添加索引,不使用Subscribe注解手动把订阅方法通过SubscriberInfoIndex.getSubscriberInfo进行返回 可以看看这篇博客

关于事件继承,比如通过Post发送了一个事件对象ArrayList如果开启了事件继承那么方法参数为Object、Collection、List、ArrayList等(只要能够上转型)都能够接受到该事件,如果没开启那么只有方法参数是ArrayList才能够接受到事件

注释1. 创建了一个Logger对象内部判断如果有自定义Logger就是用自定义的,否则判断是否有Log类和能否拿到主线程的Looper,如果能拿到就是用Log进行打印不然通过System.out进行打印

// EventBusBuilder.java
Logger getLogger() {
	 // 如果有自定义logger就使用自定义的
    if (logger != null) {
        return logger;
    } else {
        // 判断是否有Log类,并且能不能拿到主线程的Looper,如果可以使用AndroidLogger否则使用Logger.SystemOutLogger
        return Logger.AndroidLogger.isAndroidLogAvailable() && getAndroidMainLooperOrNull() != null
                ? new Logger.AndroidLogger("EventBus") :
                new Logger.SystemOutLogger();
    }
}

注释2. 如果是Android那么创建一个AndroidHandlerMainThreadSupport否则返回null

// EventBusBuilder.java
MainThreadSupport getMainThreadSupport() {
    if (mainThreadSupport != null) {
        return mainThreadSupport;
    } else if (Logger.AndroidLogger.isAndroidLogAvailable()) {
        Object looperOrNull = getAndroidMainLooperOrNull();
        return looperOrNull == null ? null :
                new MainThreadSupport.AndroidHandlerMainThreadSupport((Looper) looperOrNull);
    } else {
        return null;
    }
}
// MainThreadSupport$AndroidHandlerMainThreadSupport.class
public interface MainThreadSupport {

    boolean isMainThread();

    Poster createPoster(EventBus eventBus);

    class AndroidHandlerMainThreadSupport implements MainThreadSupport {

        private final 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);
        }
    }
}

重点来看看注释7 SubscriberMethodFinder

SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
                           boolean ignoreGeneratedIndex) {
    // null, false, false
    this.subscriberInfoIndexes = subscriberInfoIndexes;
    this.strictMethodVerification = strictMethodVerification;
    this.ignoreGeneratedIndex = ignoreGeneratedIndex;
}
// 看看findSubscriberMethods
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
	// 首先从缓存中取,如果能取到就直接返回了
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    if (subscriberMethods != null) {
        return subscriberMethods;
    }
    // 默认ignoreGeneratedIndex为false,表示是否忽略APT生成的索引
    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;
    }
}
// ignoreGeneratedIndex默认为false,接着看findUsingInfo
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
	 // 从池中取出一个FindState,如果不存在就新建一个
    FindState findState = prepareFindState();
    // 初始化subscriberClass、skipSuperClasses
    findState.initForSubscriber(subscriberClass);
    // 遍历订阅者的Class及其SuperClass(如果需要的话),找出所有被Subscribe注解的、公开的、参数是一个的方法
    while (findState.clazz != null) {
        // 如果有调用addIndex那么会回调getSubscriberInfo
        findState.subscriberInfo = getSubscriberInfo(findState);
        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 {
        	  // 通过反射去查找一个类中所有被Subscribe注解的方法
            findUsingReflectionInSingleClass(findState);
        }
        // 移动到父类如果是java、android等系统库返回null,避免影响性能,因为里面肯定没有Subscribe注解
        findState.moveToSuperclass();
    }
    return getMethodsAndRelease(findState);
}

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) {
        	  // 如果有调用addIndex那么会回调getSubscriberInfo
            SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
            if (info != null) {
                return info;
            }
        }
    }
    return null;
}

private void findUsingReflectionInSingleClass(FindState findState) {
    Method[] methods;
    try {
        // 这个方法被getMethods快尤其是对于代码很多的类比如Activity
        methods = findState.clazz.getDeclaredMethods();
    } catch (Throwable th) {
        // 好像是由于混淆的原因getDeclaredMethods可能会失败,就改成getMethod
        methods = findState.clazz.getMethods();
        // 既然通过getMethods获取方法了,那么就可以跳过父类了
        findState.skipSuperClasses = true;
    }
    for (Method method : methods) {
        int modifiers = method.getModifiers();
        // 如果不是public或者是Abstract、Static那么返回false
        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();
                        // 封装成一个SubscriberMethod保存进subscriberMethods中
                        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");
        }
    }
}
2. 订阅 EventBus.register(Object subscriber)

上文已经讲了调用findSubscriberMethods会将当前class以及其superClass中的所有被Subscribe注解修饰的公开的非abstract、final参数是一个的方法封装成一个SubscriberMethod对象保存在FindState.subscriberMethods中,所以接下来着重看看subscribe方法

public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass();
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            subscribe(subscriber, subscriberMethod);
        }
    }
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    Class<?> eventType = subscriberMethod.eventType;
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    // 获取该事件的所有订阅者信息
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions == null) {
        subscriptions = new CopyOnWriteArrayList<>();
        subscriptionsByEventType.put(eventType, subscriptions);
    } else {
        if (subscriptions.contains(newSubscription)) {
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                    + eventType);
        }
    }
	 // 根据优先级放入对应的位置,subscriptions按照优先级从大到小排列
    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;
        }
    }
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    subscribedEvents.add(eventType);

    if (subscriberMethod.sticky) {
    	  // 对应粘性事件的处理,如果有能接受到的粘性事件那么立即调用
        if (eventInheritance) {
            Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry<Class<?>, Object> entry : entries) {
                Class<?> candidateEventType = entry.getKey();
                if (eventType.isAssignableFrom(candidateEventType)) {
                    Object stickyEvent = entry.getValue();
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
            Object stickyEvent = stickyEvents.get(eventType);
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}
3. EventBus.getDefault().post(Object)、postSticky后者与前者的区别只是会将事件放入StickyEvent列表中
public void post(Object event) {
    // 获取当前线程的PostingThreadState
    PostingThreadState postingState = currentPostingThreadState.get();
    List<Object> eventQueue = postingState.eventQueue;
    eventQueue.add(event);
    // 这个判断isPosting主要是为了防止内部调用postSingleEvent,然后没找到对应的订阅方法会再调用post(NoSubscriberEvent)
    // 可以通过订阅参数为NoSubscriberEvent的方法,来检测没有找到对应的订阅方法的请求
    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;
        }
    }
}
// 如果没有找到会再post一个NoSubscriberEvent因此该方法会被调用,可以获取originalEvent拿到原始的事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveNoSubscriberEvent(NoSubscriberEvent event) {
    Log.d(TAG, event.originalEvent.toString());
}

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);
            // 分发事件,如果找到对应的接受者,返回true,否则返回false
            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) {
            // 没有找到订阅那么就发送一个NoSubscriberEvent
            post(new NoSubscriberEvent(this, event));
        }
    }
}
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;
}

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
    switch (subscription.subscriberMethod.threadMode) {
        case POSTING:
            // 当前线程直接执行
            invokeSubscriber(subscription, event);
            break;
        case MAIN:
       	  // 如果当前线程是主线程那么直接运行,不然的话放到mainThreadPoster也就是HandlerPoster实例中
            if (isMainThread) {
                invokeSubscriber(subscription, event);
            } else {
                mainThreadPoster.enqueue(subscription, event);
            }
            break;
        case MAIN_ORDERED:
        	  // Android中始终放入到mainThreadPoster中运行
            if (mainThreadPoster != null) {
                mainThreadPoster.enqueue(subscription, event);
            } else {
                // temporary: technically not correct as poster not decoupled from subscriber
                invokeSubscriber(subscription, event);
            }
            break;
        case BACKGROUND:
            // 如果当前线程是主线程那么放入backgroundPoster中,否则就直接运行
            if (isMainThread) {
                backgroundPoster.enqueue(subscription, event);
            } else {
                invokeSubscriber(subscription, event);
            }
            break;
        case ASYNC:
        	  // 放入asyncPoster中
            asyncPoster.enqueue(subscription, event);
            break;
        default:
            throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
    }
}
// invokeSubscriber,直接就是反射调用方法
void invokeSubscriber(Subscription subscription, Object event) {
    try {
        subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
    } catch (InvocationTargetException e) {
        handleSubscriberException(subscription, event, e.getCause());
    } catch (IllegalAccessException e) {
        throw new IllegalStateException("Unexpected exception", e);
    }
}
// mainThreadPoster.enqueue这里的mainThreadPoster其实就是HandlerPoster对象
public void enqueue(Subscription subscription, Object event) {
	 // 内部维护了一个PendingPost数组,如果有空余的那么就获取返回,否则新建一个
    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    synchronized (this) {
        queue.enqueue(pendingPost);
        if (!handlerActive) {
            handlerActive = true;
            // 发送一个消息启动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) {
        	  // 不断的从队列中取直到队列为空或者时间超过了maxMillisInsideHandleMessage
            PendingPost pendingPost = queue.poll();
            if (pendingPost == null) {
                synchronized (this) {
                    // Check again, this time in synchronized
                    pendingPost = queue.poll();
                    if (pendingPost == null) {
                        handlerActive = false;
                        return;
                    }
                }
            }
            eventBus.invokeSubscriber(pendingPost);
            long timeInMethod = SystemClock.uptimeMillis() - started;
            if (timeInMethod >= maxMillisInsideHandleMessage) {
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
                rescheduled = true;
                return;
            }
        }
    } finally {
        handlerActive = rescheduled;
    }
}

// backgroundPoster
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) {
            	  // 如果1秒内取不到PendPost就退出循环
                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;
    }
}
// AsyncPoster
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);
    }
}
4. EventBus.getDefault().unregister()
public synchronized void unregister(Object subscriber) {
	// 获取所有该订阅者的事件类型
    List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
    if (subscribedTypes != null) {
        for (Class<?> eventType : subscribedTypes) {
            unsubscribeByEventType(subscriber, eventType);
        }
        typesBySubscriber.remove(subscriber);
    } else {
        logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
    }
}
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
    List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions != null) {
        int size = subscriptions.size();
        for (int i = 0; i < size; i++) {
            Subscription subscription = subscriptions.get(i);
            // 如果发现是指定的订阅者那么就移除
            if (subscription.subscriber == subscriber) {
                subscription.active = false;
                subscriptions.remove(i);
                i--;
                size--;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值