EventBus源码解析下(较详细)

296 阅读4分钟

源码分析上,分析了EventBus register()的逻辑,接下来,继续查看post()的逻辑。

/** Posts the given event to the event bus. */
public void post(Object event) {
//currentPostingThreadState 是一个ThreadLocal类型
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);

//判断是否正在发送事件,防止事件多次被调用
if (!postingState.isPosting) {
    postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
    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;
    }
}
}

//发送线程状态的封装
final static class PostingThreadState {
final List<Object> eventQueue = new ArrayList<Object>();     //消息队列
boolean isPosting;   //是否正在发送
boolean isMainThread;   //是否处于主线程
Subscription subscription;   //订阅关系
Object event;   //发送的事件
boolean canceled;    
}

post()方法首先构建一个PostingThreadState,将event放入eventQueue,然后while循环发送事件。

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
//获取事件所在的类
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
//考虑继承关系,默认为true
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) {
        Log.d(TAG, "No subscribers registered for event " + eventClass);
    }
    if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
            eventClass != SubscriberExceptionEvent.class) {
        post(new NoSubscriberEvent(this, event));
    }
}
}

之后进入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;
}

该方法通过event,获取其对应的所有订阅关系,对每一个订阅关系,进行发送。

//这里的几个poster,就是eventBus初始化的时候,初始化的几个poster,事件投递者
//注意ThreadMode的四种方式
//根据@Subscribe注解的方法的ThreadMode,执行不同的处理方式
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
    case POSTING:
        invokeSubscriber(subscription, event);
        break;
    case MAIN:
        if (isMainThread) {
            invokeSubscriber(subscription, event);
        } else {
            mainThreadPoster.enqueue(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);
}
}

唤醒订阅者进行处理

//通过反射,去唤醒订阅者处理事件
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);
}
}

几个poster的介绍,mainThreadPoster继承自HandlerPoster,其实是一个handler

final class HandlerPoster extends Handler {

private final PendingPostQueue queue;
private final int maxMillisInsideHandleMessage;  //最大发送时间
private final EventBus eventBus;
private boolean handlerActive;   

HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
    super(looper);
    this.eventBus = eventBus;
    this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
    queue = new PendingPostQueue();
}

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

@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;
    }
}
}

其中,invokeSubscriber,还是调用了eventBus的inovkeSubScriber()

void invokeSubscriber(PendingPost pendingPost) {
Object event = pendingPost.event;
Subscription subscription = pendingPost.subscription;
//回收pendingPost
PendingPost.releasePendingPost(pendingPost);
if (subscription.active) {
    invokeSubscriber(subscription, event);
}
}

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

backgroundPoster

/**
* Posts events in background.
* 
* @author Markus
*/
final class BackgroundPoster implements Runnable {

private final PendingPostQueue queue;
private final EventBus eventBus;

private volatile boolean executorRunning;

BackgroundPoster(EventBus eventBus) {
    this.eventBus = eventBus;
    queue = new PendingPostQueue();
}

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) {
            Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
        }
    } finally {
        executorRunning = false;
    }
}

}

asyncPoster

/**
* Posts events in background.
* 
* @author Markus
*/
class AsyncPoster implements Runnable {

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

相比于其他两个poster,asyncPoster,没有判断,直接执行,这跟其对应的THreadMode有关,无论发送者处于什么线程,都开启一个后台线程去处理。
post()方法看完后,继续看postSticky()方法

/**
* Posts the given event to the event bus and holds on to the event (because it is sticky). The most recent sticky
* event of an event's type is kept in memory for future access by subscribers using {@link Subscribe#sticky()}.
*/
public void postSticky(Object event) {
//加同步锁,调用post()方法
synchronized (stickyEvents) {
    stickyEvents.put(event.getClass(), event);
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event);
}

先将event添加进stickyEvent队列,然后调用post()方法,发送事件。

至此,发送的流程就分析完了,但还没有结束,还有unRegister()方法,继续查看。

/** Unregisters the given subscriber from all event classes. */
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 {
    Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}

/** Unregisters the given subscriber from all event classes. */
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 {
    Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}

解绑的操作,就非常简单了,用到的两个数据集合,都是register时更新的集合。

大概的流程就分析完了,但还有一些小点,我还没有搞清楚,接下来的时间里,我会继续搞清楚几个点,并更新文章。
如有错误,不吝指教。