Skip to content

Commit d1300fb

Browse files
mrsimplemrsimple
authored andcommitted
add config and match policy
1 parent ce3640c commit d1300fb

File tree

7 files changed

+299
-57
lines changed

7 files changed

+299
-57
lines changed

README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1. greenrobot的<a href="https://github.com/greenrobot/EventBus" target="_blank">EventBus</a>是一个非常流行的开源库,但是它在使用体验上并不友好,例如它的订阅函数必须以onEvent开头,并且如果需要指定该函数运行的线程则又要根据规则将函数名加上执行线程的模式名,这么说很难理解,比如我要将某个事件的接收函数执行在主线程,那么函数名必须为onEventMainThread。那如果我一个订阅者中有两个参数名相同,且都执行在主线程的接收函数呢? 这个时候似乎它就没法处理了。而且规定死了函数命名,那就不能很好的体现该函数的功能,也就是函数的自文档性。AndroidEventBus使用注解来标识接收函数,这样函数名不受限制,比如我可以把接收函数名写成updateUserInfo(Person info),这样就灵活得多了。
1616
2. 另一个不同就是AndroidEventBus增加了一个额外的tag来标识每个接收函数可接收的事件的tag,这类似于Broadcast中的action,比如每个Broadcast对应一个或者多个action,当你发广播时你得指定这个广播的action,然后对应的广播接收器才能收到.greenrobot的EventBus只是根据函数参数类型来标识这个函数是否可以接收某个事件,这样导致只要是参数类型相同,任何的事件它都可以接收到,这样的投递原则就很局限了。比如我有两个事件,一个添加用户的事件, 一个删除用户的事件,他们的参数类型都为User,那么greenrobot的EventBus大概是这样的:
1717

18-
```java
18+
```
1919
2020
private void onEventMainThread(User aUser) {
2121
// code
@@ -32,7 +32,7 @@ private void onEventMainThread(User aUser) {
3232

3333
* 1. 注册事件接收对象
3434

35-
```java
35+
```
3636
3737
public class YourActivity extends Activity {
3838
@@ -56,7 +56,8 @@ public class YourActivity extends Activity {
5656

5757
* 2. 通过Subscriber注解来标识事件接收对象中的接收方法
5858

59-
```java
59+
```
60+
6061
public class YourActivity extends Activity {
6162
6263
// code ......
@@ -87,7 +88,8 @@ public class YourActivity extends Activity {
8788
}
8889
}
8990
90-
```
91+
```
92+
9193
User类大致如下 :
9294
```
9395
public class User {
@@ -104,18 +106,22 @@ public class YourActivity extends Activity {
104106

105107
* 3. 在其他组件,例如Activity, Fragment,Service中发布事件
106108

107-
```java
109+
```
108110
109111
EventBus.getDefault().post(new User("android"));
110112
111113
// post a event with tag, the tag is like broadcast's action
112114
EventBus.getDefault().post(new User("mr.simple"), "my_tag");
113115
114-
```
115-
发布事件之后,注册了该事件类型的对象就会接收到响应的事件.
116+
```
116117

118+
发布事件之后,注册了该事件类型的对象就会接收到响应的事件.
117119

118120

121+
## 感谢
122+
在此非常感谢网友“淡蓝色的星期三”提出的bug以及反馈,也希望更多的朋友能够加入到Android EventBus的开发中来。
123+
124+
119125
## License
120126
```
121127
Copyright (C) 2015 Mr.Simple <bboyfeiyu@gmail.com>

src/org/simple/eventbus/EventBus.java

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818

1919
import android.util.Log;
2020

21-
import org.simple.eventbus.handler.AsyncEventHandler;
22-
import org.simple.eventbus.handler.DefaultEventHandler;
21+
import org.simple.eventbus.config.EventBusConfig;
2322
import org.simple.eventbus.handler.EventHandler;
24-
import org.simple.eventbus.handler.UIThreadEventHandler;
23+
import org.simple.eventbus.matchpolicy.MatchPolicy;
2524

2625
import java.util.HashMap;
27-
import java.util.LinkedList;
2826
import java.util.List;
2927
import java.util.Map;
3028
import java.util.Queue;
@@ -88,6 +86,10 @@ protected java.util.Queue<EventType> initialValue() {
8886
* The Default EventBus instance
8987
*/
9088
private static EventBus sDefaultBus;
89+
/**
90+
* the event bus config
91+
*/
92+
private EventBusConfig mBusConfig = new EventBusConfig();
9193

9294
/**
9395
* private Constructor
@@ -103,6 +105,7 @@ private EventBus() {
103105
*/
104106
public EventBus(String desc) {
105107
mDesc = desc;
108+
initWithConfig(mBusConfig);
106109
}
107110

108111
/**
@@ -119,6 +122,18 @@ public static EventBus getDefault() {
119122
return sDefaultBus;
120123
}
121124

125+
/**
126+
* init event bus with EventBusConfig
127+
*
128+
* @param config
129+
*/
130+
public void initWithConfig(EventBusConfig config) {
131+
mDispatcher.mMatchPolicy = config.getMatchPolicy();
132+
mDispatcher.mUIThreadEventHandler = config.getUIThreadEventHandler();
133+
mDispatcher.mPostThreadHandler = config.getPostThreadHandler();
134+
mDispatcher.mAsyncEventHandler = config.getAsyncEventHandler();
135+
}
136+
122137
/**
123138
* register a subscriber into the mSubcriberMap, the key is subscriber's
124139
* method's name and tag which annotated with {@see Subcriber}, the value is
@@ -216,22 +231,26 @@ private class EventDispatcher {
216231
/**
217232
* 将接收方法执行在UI线程
218233
*/
219-
UIThreadEventHandler mUIThreadEventHandler = new UIThreadEventHandler();
234+
EventHandler mUIThreadEventHandler;
220235

221236
/**
222237
* 哪个线程执行的post,接收方法就执行在哪个线程
223238
*/
224-
EventHandler mPostThreadHandler = new DefaultEventHandler();
239+
EventHandler mPostThreadHandler;
225240

226241
/**
227242
* 异步线程中执行订阅方法
228243
*/
229-
EventHandler mAsyncEventHandler = new AsyncEventHandler();
244+
EventHandler mAsyncEventHandler;
230245

231246
/**
232247
* 缓存一个事件类型对应的可EventType列表
233248
*/
234249
private Map<Class<?>, List<EventType>> mCacheEventTypes = new ConcurrentHashMap<Class<?>, List<EventType>>();
250+
/**
251+
* 事件匹配策略,根据策略来查找对应的EventType集合
252+
*/
253+
MatchPolicy mMatchPolicy;
235254

236255
/**
237256
* @param event
@@ -243,16 +262,34 @@ void dispatchEvents(Object aEvent) {
243262
}
244263
}
245264

265+
/**
266+
* 根据aEvent查找到所有匹配的集合,然后处理事件
267+
*
268+
* @param type
269+
* @param aEvent
270+
*/
246271
private void deliveryEvent(EventType type, Object aEvent) {
247272
Class<?> eventClass = aEvent.getClass();
248-
List<EventType> types = mCacheEventTypes.containsKey(eventClass)
249-
? mCacheEventTypes.get(eventClass)
250-
: findAllEventType(eventClass, type.tag);
251-
for (EventType eventType : types) {
273+
List<EventType> eventTypes = null;
274+
// 如果有缓存则直接从缓存中取
275+
if (mCacheEventTypes.containsKey(eventClass)) {
276+
eventTypes = mCacheEventTypes.get(eventClass);
277+
} else {
278+
eventTypes = mMatchPolicy.findMatchEventTypes(type, aEvent);
279+
mCacheEventTypes.put(eventClass, eventTypes);
280+
}
281+
282+
for (EventType eventType : eventTypes) {
252283
handleEvent(eventType, aEvent);
253284
}
254285
}
255286

287+
/**
288+
* 处理单个事件
289+
*
290+
* @param eventType
291+
* @param aEvent
292+
*/
256293
private void handleEvent(EventType eventType, Object aEvent) {
257294
List<Subscription> subscriptions = mSubcriberMap.get(eventType);
258295
if (subscriptions == null) {
@@ -267,44 +304,6 @@ private void handleEvent(EventType eventType, Object aEvent) {
267304
}
268305
}
269306

270-
/**
271-
* 根据post的参数类型来要查找该类型的所有父类、接口类型,并且构造为EventType,然后到订阅表中查找对应的接收者.
272-
* 例如用户在订阅函数时参数类型设置为List
273-
* <String>,但在post事件时传递的参数却是ArrayList<String>类型,此时该事件需要匹配到订阅类型为List
274-
* <String>,因此需要做出处理.
275-
*
276-
* @param aEvent 用户发布的事件
277-
* @param tag 发布的事件的tag
278-
* @return
279-
*/
280-
private List<EventType> findAllEventType(Class<?> eventClass, String tag) {
281-
List<EventType> result = new LinkedList<EventType>();
282-
while (eventClass != null) {
283-
result.add(new EventType(eventClass, tag));
284-
addInterfaces(result, eventClass.getInterfaces(), tag);
285-
eventClass = eventClass.getSuperclass();
286-
}
287-
288-
// 缓存到map中
289-
mCacheEventTypes.put(eventClass, result);
290-
return result;
291-
}
292-
293-
/**
294-
* 获取该事件的所有接口类型
295-
*
296-
* @param eventTypes 存储列表
297-
* @param interfaces 事件实现的所有接口
298-
*/
299-
private void addInterfaces(List<EventType> eventTypes, Class<?>[] interfaces, String tag) {
300-
for (Class<?> interfaceClass : interfaces) {
301-
if (!eventTypes.contains(interfaceClass)) {
302-
eventTypes.add(new EventType(interfaceClass, tag));
303-
addInterfaces(eventTypes, interfaceClass.getInterfaces(), tag);
304-
}
305-
}
306-
}
307-
308307
private EventHandler getEventHandler(ThreadMode mode) {
309308
if (mode == ThreadMode.ASYNC) {
310309
return mAsyncEventHandler;

src/org/simple/eventbus/EventType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public final class EventType {
3636
/**
3737
* 函数的tag
3838
*/
39-
String tag = DEFAULT_TAG;
39+
public String tag = DEFAULT_TAG;
4040

4141
/**
4242
* @param aClass
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2014-2015 Umeng, Inc
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package org.simple.eventbus.config;
26+
27+
import org.simple.eventbus.handler.AsyncEventHandler;
28+
import org.simple.eventbus.handler.DefaultEventHandler;
29+
import org.simple.eventbus.handler.EventHandler;
30+
import org.simple.eventbus.handler.UIThreadEventHandler;
31+
import org.simple.eventbus.matchpolicy.DefaultMatchPolicy;
32+
import org.simple.eventbus.matchpolicy.MatchPolicy;
33+
34+
/**
35+
* Event Bus Configuration, like builder mode
36+
*
37+
* @author mrsimple
38+
*/
39+
public final class EventBusConfig {
40+
41+
/**
42+
* 将接收方法执行在UI线程
43+
*/
44+
EventHandler mUIThreadEventHandler = new UIThreadEventHandler();
45+
46+
/**
47+
* 哪个线程执行的post,接收方法就执行在哪个线程
48+
*/
49+
EventHandler mPostThreadHandler = new DefaultEventHandler();
50+
51+
/**
52+
* 异步线程中执行订阅方法
53+
*/
54+
EventHandler mAsyncEventHandler = new AsyncEventHandler();
55+
/**
56+
* 订阅函数匹配策略类
57+
*/
58+
MatchPolicy mMatchPolicy = new DefaultMatchPolicy();
59+
60+
public EventBusConfig setMatchPolicy(MatchPolicy mMatchPolicy) {
61+
this.mMatchPolicy = mMatchPolicy;
62+
return this;
63+
}
64+
65+
public EventBusConfig setUIThreadEventHandler(EventHandler handler) {
66+
this.mUIThreadEventHandler = handler;
67+
return this;
68+
}
69+
70+
public EventBusConfig setPostThreadHandler(EventHandler handler) {
71+
this.mPostThreadHandler = handler;
72+
return this;
73+
}
74+
75+
public EventBusConfig setAsyncEventHandler(EventHandler handler) {
76+
this.mAsyncEventHandler = handler;
77+
return this;
78+
}
79+
80+
public EventHandler getUIThreadEventHandler() {
81+
return mUIThreadEventHandler;
82+
}
83+
84+
public EventHandler getPostThreadHandler() {
85+
return mPostThreadHandler;
86+
}
87+
88+
public EventHandler getAsyncEventHandler() {
89+
return mAsyncEventHandler;
90+
}
91+
92+
public MatchPolicy getMatchPolicy() {
93+
return mMatchPolicy;
94+
}
95+
96+
}

0 commit comments

Comments
 (0)