文章目录
一、EventBus 中主线程支持类
二、MainThreadSupport 解析
三、MainThreadSupport 解析
四、PendingPost 链表
一、EventBus 中主线程支持类
在 EventBus.postToSubscription 方法中 , 如果当前线程是子线程 , 则调用如下方法 , 切换到主线程执行 ;
// 假如发布线程是子线程 , 则将事件加入队列 , 通过 Handler 切换线程执行 mainThreadPoster.enqueue(subscription, event);
mainThreadPoster 是通过 mainThreadSupport.createPoster(this) 创建的 ;
注意 , 创建 mainThreadPoster 时 , 会判定当前线程是否是主线程 , 如果当前线程是主线程 , 才会创建 mainThreadPoster , 否则为空 ;
EventBus 中 mainThreadPoster 相关代码 :
public class EventBus { // @Nullable private final MainThreadSupport mainThreadSupport; // @Nullable private final Poster mainThreadPoster; EventBus(EventBusBuilder builder) { mainThreadSupport = builder.getMainThreadSupport(); // 如果当前线程是主线程 , 才会创建 mainThreadPoster , 否则为空 mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null; } private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { // 获取该 订阅方法 的线程模式 switch (subscription.subscriberMethod.threadMode) { case MAIN: if (isMainThread) { // 假如在主线程中 , 直接调用 invokeSubscriber(subscription, event); } else { // 假如发布线程是子线程 , 则将事件加入队列 , 通过 Handler 切换线程执行 mainThreadPoster.enqueue(subscription, event); } break; } } }
二、MainThreadSupport 解析
MainThreadSupport 是一个接口 , 在 AndroidHandlerMainThreadSupport 实现类中的 createPoster 方法中 , 创建了一个 HandlerPoster ;
package org.greenrobot.eventbus; import android.os.Looper; /** * 接口到“主”线程,可以是您喜欢的任何线程。通常在Android上使用Android的主线程。 */ 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); } } }
三、MainThreadSupport 解析
调用 mainThreadSupport.createPoster(this) 创建的对象就是 HandlerPoster 对象 , 其本质是一个 Handler ;
调用 void enqueue(Subscription subscription, Object event) 方法 , 将订阅者和订阅方法 , 事件对象 传入该方法 , 将 订阅者 和 事件对象 加入到 PendingPost 链表中 ;
同时调用 sendMessage(obtainMessage()) 方法 , 向 Handler 发送消息 , 执行 handleMessage 方法中的业务逻辑 ;
在 handleMessage 方法中 , PendingPost pendingPost = queue.poll() 取出链表元素 , 每个元素中封装了 订阅者 和 事件对象 , eventBus.invokeSubscriber(pendingPost); 通过反射执行订阅方法 ;
HandlerPoster 源码 :
public class HandlerPoster extends Handler implements Poster { private final PendingPostQueue queue; private final int maxMillisInsideHandleMessage; private final EventBus eventBus; private boolean handlerActive; protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) { super(looper); this.eventBus = eventBus; this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage; queue = new PendingPostQueue(); } // 将订阅者和订阅方法 , 事件对象 传入该方法 public void enqueue(Subscription subscription, Object event) { // PendingPost 是一个链表数据结构 , 将所有的 事件对象 , 订阅者 都封装在了该链表中 ; // 将 订阅者 和 事件对象 加入到 PendingPost 链表中 PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); synchronized (this) { queue.enqueue(pendingPost); if (!handlerActive) { handlerActive = true; // 向 Handler 发送消息 , 执行 handleMessage 方法 if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } } } } // 不断取出 PendingPost 链表中的数据 , 执行订阅方法 @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; } } }
四、PendingPost 链表
PendingPost 是一个链表数据结构 , 将所有的 事件对象 , 订阅者 都封装在了该链表中 ;
final class PendingPost { private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>(); Object event; Subscription subscription; PendingPost next; }