-
Notifications
You must be signed in to change notification settings - Fork 390
Expand file tree
/
Copy pathEventBus.java
More file actions
508 lines (450 loc) · 15.7 KB
/
EventBus.java
File metadata and controls
508 lines (450 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
/*
* Copyright (C) 2015 Mr.Simple <bboyfeiyu@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.simple.eventbus;
import org.simple.eventbus.handler.AsyncEventHandler;
import org.simple.eventbus.handler.DefaultEventHandler;
import org.simple.eventbus.handler.EventHandler;
import org.simple.eventbus.handler.UIThreadEventHandler;
import org.simple.eventbus.matchpolicy.DefaultMatchPolicy;
import org.simple.eventbus.matchpolicy.MatchPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
* EventBus是AndroidEventBus框架的核心类,也是用户的入口类.它存储了用户注册的订阅者信息和方法,
* 事件类型和该事件对应的tag标识一个种类的事件{@see EventType},每一种事件对应有一个或者多个订阅者{@see Subscription}
* ,订阅者中的订阅函数通过{@see Subcriber}注解来标识tag和线程模型,这样使得用户体检较为友好,代码也更加整洁.
* <p>
* 用户需要在发布事件前通过@{@see #register(Object)}方法将订阅者注册到EventBus中,EventBus会解析该订阅者中使用了
* {@see Subcriber}标识的函数,并且将它们以{@see EventType}为key,以{@see Subscription}
* 列表为value存储在map中. 当用户post一个事件时通过事件到map中找到对应的订阅者,然后按照订阅函数的线程模型将函数执行在对应的线程中.
* <p>
* 最后在不在需要订阅事件时,应该调用{@see #unregister(Object)}函数注销该对象,避免内存泄露!
* 例如在Activity或者Fragment的onDestory函数中注销对Activity或者Fragment的订阅.
* <p>
* 注意 : 如果发布的事件的参数类型是订阅的事件参数的子类,订阅函数默认也会被执行。例如你在订阅函数中订阅的是List<String>类型的事件,
* 但是在发布时发布的是ArrayList<String>的事件,
* 因此List<String>是一个泛型抽象,而ArrayList<String>才是具体的实现
* ,因此这种情况下订阅函数也会被执行。如果你需要订阅函数能够接收到的事件类型必须严格匹配 ,你可以构造一个EventBusConfig对象,
* 然后设置MatchPolicy然后在使用事件总线之前使用该EventBusConfig来初始化事件总线. <code>
* EventBusConfig config = new EventBusConfig();
config.setMatchPolicy(new StrictMatchPolicy());
EventBus.getDefault().initWithConfig(config);
* </code>
*
* @author mrsimple
*/
public final class EventBus {
/**
* default descriptor
*/
private static final String DESCRIPTOR = EventBus.class.getSimpleName();
/**
* 事件总线描述符描述符
*/
private String mDesc = DESCRIPTOR;
/**
* EventType-Subcriptions map
*/
private final Map<EventType, CopyOnWriteArrayList<Subscription>> mSubcriberMap = new ConcurrentHashMap<EventType, CopyOnWriteArrayList<Subscription>>();
/**
*
*/
private List<EventType> mStickyEvents = Collections
.synchronizedList(new LinkedList<EventType>());
/**
* the thread local event queue, every single thread has it's own queue.
*/
ThreadLocal<Queue<EventType>> mLocalEvents = new ThreadLocal<Queue<EventType>>() {
protected java.util.Queue<EventType> initialValue() {
return new ConcurrentLinkedQueue<EventType>();
};
};
/**
* the event dispatcher
*/
EventDispatcher mDispatcher = new EventDispatcher();
/**
* the subscriber method hunter, find all of the subscriber's methods
* annotated with @Subcriber
*/
SubsciberMethodHunter mMethodHunter = new SubsciberMethodHunter(mSubcriberMap);
/**
* The Default EventBus instance
*/
private static EventBus sDefaultBus;
/**
* private Constructor
*/
private EventBus() {
this(DESCRIPTOR);
}
/**
* constructor with desc
*
* @param desc the descriptor of eventbus
*/
public EventBus(String desc) {
mDesc = desc;
}
/**
* @return
*/
public static EventBus getDefault() {
if (sDefaultBus == null) {
synchronized (EventBus.class) {
if (sDefaultBus == null) {
sDefaultBus = new EventBus();
}
}
}
return sDefaultBus;
}
/**
* register a subscriber into the mSubcriberMap, the key is subscriber's
* method's name and tag which annotated with {@see Subcriber}, the value is
* a list of Subscription.
*
* @param subscriber the target subscriber
*/
public void register(Object subscriber) {
if (subscriber == null) {
return;
}
synchronized (this) {
mMethodHunter.findSubcribeMethods(subscriber);
}
}
/**
* 以sticky的形式注册,则会在注册成功之后迭代所有的sticky事件
*
* @param subscriber
*/
public void registerSticky(Object subscriber) {
this.register(subscriber);
// 处理sticky事件
mDispatcher.dispatchStickyEvents(subscriber);
}
/**
* @param subscriber
*/
public void unregister(Object subscriber) {
if (subscriber == null) {
return;
}
synchronized (this) {
mMethodHunter.removeMethodsFromMap(subscriber);
}
}
/**
* post a event
*
* @param event
*/
public void post(Object event) {
post(event, EventType.DEFAULT_TAG);
}
public void post(Class<?> eventClass) {
post(null, EventType.DEFAULT_TAG, eventClass);
}
public void post(String tag) {
post(null, tag, null);
}
public void post(String tag, Class<?> eventClass) {
post(null, tag, eventClass);
}
/**
* 发布事件
*
* @param event 要发布的事件
* @param tag 事件的tag, 类似于BroadcastReceiver的action
*/
public void post(Object event, String tag) {
post(event, tag, null == event ? null : event.getClass());
}
/**
* 发布事件
*
* @param event 要发布的事件
* @param tag 事件的tag, 类似于BroadcastReceiver的action
* @param eventClass 事件类类型
*/
public void post(Object event, String tag, Class<?> eventClass) {
mLocalEvents.get().offer(new EventType(eventClass, tag));
mDispatcher.dispatchEvents(event);
}
/**
* 发布Sticky事件,tag为EventType.DEFAULT_TAG
*
* @param event
*/
public void postSticky(Object event) {
postSticky(event, EventType.DEFAULT_TAG);
}
public void postSticky(Class<?> eventClass) {
postSticky(null, EventType.DEFAULT_TAG, eventClass);
}
public void postSticky(String tag) {
postSticky(null, tag, null);
}
public void postSticky(String tag, Class<?> eventClass) {
postSticky(null, tag, eventClass);
}
/**
* 发布含有tag的Sticky事件
*
* @param event 事件
* @param tag 事件tag
*/
public void postSticky(Object event, String tag) {
postSticky(event, tag, event == null ? null : event.getClass());
}
public void postSticky(Object event, String tag, Class<?> eventClass) {
EventType eventType = new EventType(eventClass, tag);
eventType.event = event;
mStickyEvents.add(eventType);
}
public void removeStickyEvent(String tag) {
removeStickyEvent(null, tag);
}
public void removeStickyEvent(Class<?> eventClass) {
removeStickyEvent(eventClass, EventType.DEFAULT_TAG);
}
/**
* 移除Sticky事件
*
* @param type
*/
public void removeStickyEvent(Class<?> eventClass, String tag) {
Iterator<EventType> iterator = mStickyEvents.iterator();
while (iterator.hasNext()) {
EventType eventType = iterator.next();
if (eventType.equals(eventClass, tag)) {
iterator.remove();
}
}
}
public List<EventType> getStickyEvents() {
return mStickyEvents;
}
/**
* 设置订阅函数匹配策略
*
* @param policy 匹配策略
*/
public void setMatchPolicy(MatchPolicy policy) {
mDispatcher.mMatchPolicy = policy;
}
/**
* 设置执行在UI线程的事件处理器
*
* @param handler
*/
public void setUIThreadEventHandler(EventHandler handler) {
mDispatcher.mUIThreadEventHandler = handler;
}
/**
* 设置执行在post线程的事件处理器
*
* @param handler
*/
public void setPostThreadHandler(EventHandler handler) {
mDispatcher.mPostThreadHandler = handler;
}
/**
* 设置执行在异步线程的事件处理器
*
* @param handler
*/
public void setAsyncEventHandler(EventHandler handler) {
mDispatcher.mAsyncEventHandler = handler;
}
/**
* 返回订阅map
*
* @return
*/
public Map<EventType, CopyOnWriteArrayList<Subscription>> getSubscriberMap() {
return mSubcriberMap;
}
/**
* 获取等待处理的事件队列
*
* @return
*/
public Queue<EventType> getEventQueue() {
return mLocalEvents.get();
}
/**
* clear the events and subcribers map
*/
public synchronized void clear() {
mLocalEvents.get().clear();
mSubcriberMap.clear();
}
/**
* get the descriptor of EventBus
*
* @return the descriptor of EventBus
*/
public String getDescriptor() {
return mDesc;
}
public EventDispatcher getDispatcher() {
return mDispatcher;
}
/**
* 事件分发器
*
* @author mrsimple
*/
private class EventDispatcher {
/**
* 将接收方法执行在UI线程
*/
EventHandler mUIThreadEventHandler = new UIThreadEventHandler();
/**
* 哪个线程执行的post,接收方法就执行在哪个线程
*/
EventHandler mPostThreadHandler = new DefaultEventHandler();
/**
* 异步线程中执行订阅方法
*/
EventHandler mAsyncEventHandler = new AsyncEventHandler();
/**
* 缓存一个事件类型对应的可EventType列表
*/
private Map<EventType, List<EventType>> mCacheEventTypes = new ConcurrentHashMap<EventType, List<EventType>>();
/**
* 事件匹配策略,根据策略来查找对应的EventType集合
*/
MatchPolicy mMatchPolicy = new DefaultMatchPolicy();
/**
* @param event
*/
void dispatchEvents(Object aEvent) {
Queue<EventType> eventsQueue = mLocalEvents.get();
while (eventsQueue.size() > 0) {
deliveryEvent(eventsQueue.poll(), aEvent);
}
}
/**
* 根据aEvent查找到所有匹配的集合,然后处理事件
*
* @param type
* @param aEvent
*/
private void deliveryEvent(EventType type, Object aEvent) {
// 如果有缓存则直接从缓存中取
List<EventType> eventTypes = getMatchedEventTypes(type, aEvent);
// 迭代所有匹配的事件并且分发给订阅者
for (EventType eventType : eventTypes) {
handleEvent(eventType, aEvent);
}
}
/**
* 处理单个事件
*
* @param eventType
* @param aEvent
*/
private void handleEvent(EventType eventType, Object aEvent) {
List<Subscription> subscriptions = mSubcriberMap.get(eventType);
if (subscriptions == null) {
return;
}
for (Subscription subscription : subscriptions) {
final ThreadMode mode = subscription.threadMode;
EventHandler eventHandler = getEventHandler(mode);
// 处理事件
eventHandler.handleEvent(subscription, aEvent);
}
}
private List<EventType> getMatchedEventTypes(EventType type, Object aEvent) {
List<EventType> eventTypes = null;
// 如果有缓存则直接从缓存中取
if (mCacheEventTypes.containsKey(type)) {
eventTypes = mCacheEventTypes.get(type);
} else {
eventTypes = mMatchPolicy.findMatchEventTypes(type, type.getEventClass());
mCacheEventTypes.put(type, eventTypes);
}
return eventTypes != null ? eventTypes : new ArrayList<EventType>();
}
void dispatchStickyEvents(Object subscriber) {
for (EventType eventType : mStickyEvents) {
handleStickyEvent(eventType, subscriber);
}
}
/**
* 处理单个Sticky事件
*
* @param eventType
* @param aEvent
*/
private void handleStickyEvent(EventType eventType, Object subscriber) {
List<EventType> eventTypes = getMatchedEventTypes(eventType, eventType.event);
// 事件
Object event = eventType.event;
for (EventType foundEventType : eventTypes) {
final List<Subscription> subscriptions = mSubcriberMap.get(foundEventType);
if (subscriptions == null) {
continue;
}
for (Subscription subItem : subscriptions) {
final ThreadMode mode = subItem.threadMode;
EventHandler eventHandler = getEventHandler(mode);
// 如果订阅者为空,那么该sticky事件分发给所有订阅者.否则只分发给该订阅者
if (isTarget(subItem, subscriber)
&& (subItem.eventType.equals(foundEventType)
|| subItem.eventType.isAssignableFromEventClass(foundEventType))) {
// 处理事件
eventHandler.handleEvent(subItem, event);
}
}
}
}
/**
* 如果传递进来的订阅者不为空,那么该Sticky事件只传递给该订阅者(注册时),否则所有订阅者都传递(发布时).
*
* @param item
* @param subscriber
* @return
*/
private boolean isTarget(Subscription item, Object subscriber) {
Object cacheObject = item.subscriber != null ? item.subscriber.get() : null;
return subscriber == null || (subscriber != null
&& cacheObject != null && cacheObject.equals(subscriber));
}
private EventHandler getEventHandler(ThreadMode mode) {
if (mode == ThreadMode.ASYNC) {
return mAsyncEventHandler;
}
if (mode == ThreadMode.POST) {
return mPostThreadHandler;
}
return mUIThreadEventHandler;
}
} // end of EventDispatcher
}