- 1 概述
- 2 原理
- 3 使用
- 4 源码
- 5 总结
https://greenrobot.org/eventbus/documentation/
https://github.com/greenrobot/EventBus
1 概述
EventBus Publisher 将 Event 交给 EventBus
EventBus 转交给 Subscriber
Subscriber 在其回调中消费处理 Event
提供能力:
- ThreadMode
- StickyEvent (ClassType <-> Event)
- subscribe priority & Event Cancle
2 原理
-
register 将会在该类内部进行解析,带有 subscribe 注解的方法会被提取为观察者接受回调
-
post 发送 event
-
threadMode 处理线程切换,利用队列来保存Event 进行线程调度
-
StickyEvent @Subscribe(sticky = true) 则会在 subscriber register 时候将所有的 stickyEvent 回调所有 注解sticky = true 的 subscribe method
-
Priority: 解析 @Subscribe(priority = 1) 将在插入 subscription 的时候将该订阅 位置靠前 default priority = 0
-
Cancel 在 for 中会分发 Event 到 每个 Subscription Cancel --> break
-
index 索引 解析形成 SubscribeMethod 采用注解解析生成器做处理,不使用默认的反射提高效率
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
...
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
3 使用
官方教程
https://greenrobot.org/eventbus/documentation/how-to-get-started/
代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent(System.currentTimeMillis()+""));
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void homeText(MessageEvent event) {
textView.setText(event.content);
}
@Override
protected void onStart() {
EventBus.getDefault().register(this);
super.onStart();
}
@Override
protected void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
4 源码
- EventBus
- eventTypesCache
- DEFAULT_BUILDER
- defaultInstance
- eventTypesCache
- subscriptionsByEventType
- typesBySubscriber
- stickyEvents
- mainThreadSupport
- mainThreadPoster
- backgroundPoster
- asyncPoster
- subscriberMethodFinder
- executorService
- Poster
- enqueue
-
Subscription
- subscriber
- subscriberMethod
-
SubscriberMethod
- method
- threadMode
- eventType
- priority
- sticky
5 总结
- 注解
- 观察者模式
- 线程调度
后台线程 和 主线程 切换:
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 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);
}
}
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);
}
}
五种模式的特征各不相同
网友评论