EventBus定义
EventBus 是Greenrobot开源的一款轻量级的发布/订阅事件总线。
EventBus-Publish-Subscribe.png
- Publisher方发布Event事件
- Subciber方响应事件,执行响应函数onEvent()
优点
简化组件之间的通信,在Activitys, Fragments,和后台线程中都表现良好。
避免复杂且容易出错的依赖关系和生命周期问题
如何使用:
1 定义事件:
public static class MessageEvent { /* Additional fields if needed */ }
2 在你需要响应事件的地方定义Subscribe函数。添加@Subscribe注解和threadMode 类型(后面会详情介绍threadMode)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
3 在你的Subscribe函数所在组件的生命周期函数中执行注册和注销函数
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
4 发送事件
EventBus.getDefault().post(new MessageEvent());
ThreadMode
EventBus共包括4种模式:
- POSTING:在post所在线程执行
- MAIN:在主线程(UI thread)中执行
- BACKGROUND:在后台线程中执行,适合耗时短的处理
- ASYNC:在单独线程中执行,适合耗时较长的处理
源码分析
void register(Object subscriber)
register()解析当前subscriber的class,获取所有Subscribe 函数,保存到对应的events的map中。
subscriberMethodFinder是其负责解析class的辅助函数。
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
保存在subscriptionsByEventType中,字典类型,Event class 和 subscription list集合一一对应。
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
void post(Object event)
post 发送event到EventBus的eventQueue。
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
发送队列里的所有event
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
获取event的所有subscriber 函数
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
}
根据threadModel类型,执行subscriber 函数
......
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
break;
......
反射方式执行:
void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} ......
}
异步线程处理:EventBus内部维护一个线程池负责处理
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
总结:
EventBus 使用非常简单,代码结构非常清晰,非常方便阅读,值得学习。
网友评论