xBus-简洁的EventBus实现

Demo地址:MyXBus

基于发布订阅(Pub/Sub)模式的一个事件消息库,使用通用的 register(target), unregister(target), post(event) 消息通信接口,能有效的减少甚至消除Android应用中异步任务逻辑和界面更新之间的耦合,实现模块化,提高开发效率。

Maven Central

  • 2015.09.15 1.0.2 - 修复多线程发送事件的同步问题
  • 2015.08.18 1.0.1 - 修复 unresiger() 的空指针问题
  • 2015.08.08 1.0.0 - 基本功能全部完成,发布1.0.0正式版

使用指南

Gradle集成

1
compile 'com.mcxiaoke.xbus:bus:1.0.+'

接收事件

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
public class SimpleActivity extends Activity {

@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 注册
Bus.getDefault().register(this);
}

@Override
protected void onDestroy() {
super.onDestroy();
// 取消注册
Bus.getDefault().unregister(this);
}

@BusReceiver
public void onStringEvent(String event) {
// handle your event
// 这里处理事件
}

@BusReceiver
public void onSomeEvent(SomeEventClass event) {
// SomeEventClass表示任意的自定义类
// handle your event
// 这里处理事件
}

@BusReceiver
public void onObjectEvent(Object event) {
// 不建议使用Object,会收到所有类型的事件
// handle your event
// 这里处理事件
}
}

发送事件

然后在需要的地方调用 post(event) 发送事件通知,如 Service 或某个线程里,可以在任何地方发送事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 比如在IntentService里
public class SimpleService extends IntentService {

public SimpleService() {
super("SimpleService");
}

@Override
protected void onHandleIntent(final Intent intent) {
// 这里是举例,可以在任何地方发送事件
Bus.getDefault().post("String Event");
Bus.getDefault().post(new SomeEventClass());
Bus.getDefault().post(new Object());
}
}

高级用法

任何地方注册

你还可以选择在 onStart() 里注册,在 onStop() 里取消注册。你完全可以在任何地方注册和取消注册,没有任何限制。但是建议你在生命周期事件方法里注册和取消注册,如 Activity/Fragment/ServiceonCreate/onDestroy 方法里, register()unregister() 建议配对使用,避免内存泄露。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected void onStart() {
super.onStart();
// you can also register here
Bus.getDefault().register(this);
}

@Override
protected void onStop() {
super.onStop();
// you can also unregister here
Bus.getDefault().unregister(this);
}

自定义 Bus

你也可以不使用默认的 Bus.getDefault(),改用自己创建的 Bus 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainApp extends Application {

private Bus mBus = new Bus();

@Override
public void onCreate() {
super.onCreate();
}

public Bus getBus() {
return mBus;
}
}

Debug

默认不输出任何LOG信息,可以这样启用调试模式:

1
public Bus setDebug(final boolean debug)

MethodFinder

默认使用注解(@BusReceiver)识别事件接收器方法,可以这样修改 :

1
public Bus setMethodFinder(final MethodFinder finder)

默认使用的是 AnnotationMethodFinder,只有使用了 @BusReceiver 的方法才可以接受事件。

可选使用 NamedMethodFinderNamedMethodFinder 使用方法名识别,默认方法名是 onEvent ,你可以指定其它的方法名。

使用 NamedMethodFinder 会比使用 AnnotationMethodFinder 效率高一点,因为它忽略注解,直接使用方法名字符串匹配。一般使用,两者差别不大。

你还可以实现 MethodFinder 接口,自定义其它的事件接收器方法匹配模式:

1
2
3
4
interface MethodFinder {

Set<MethodInfo> find(final Bus bus, final Class<?> targetClass);
}

StrictMode

宽泛匹配模式

默认情况下, Bus 使用宽泛的事件类型匹配模式,事件参数会匹配它的父类和接口,如果你调用 post(String),那么这几个方法都会收到举例:

1
2
3
4
5
6
7
8
9
10
11
12
// 如果你调用这个方法,发送一个StringBuilder类型的事件
Bus.getDefault().post(new StringBuilder("Event"));

// 这几个方法会收到事件
public void onEvent1(StringBuilder event) // 匹配,类型相符
public void onEvent2(Object event) // 匹配,StringBuilder是Object的子类
public void onEvent3(CharSequence event) // 匹配,StringBuilder是CharSequence的实现类
public void onEvent4(Serializable event) // 匹配,StringBuilder实现了Serializable接口

// 这几个方法不会收到事件
public void onEvent5(Exception event) 不匹配,Exception与String完全无关
public void onEvent6(String event) // 不匹配,StringBuilder不能转换成String类型

对于 post(event)onEvent(EventType) ,匹配规则是:如果 event.getClass() 可以强制转换成 EventType,那么匹配成功,能收到事件。

严格匹配模式

可以使用下面的方法更改默认行为,使用严格的事件类型匹配模式:

1
public Bus setStrictMode(final boolean strictMode)

启用严格匹配模式后,发送和接受方法的参数类型必须严格匹配才能收到事件,举例:

1
2
3
4
5
6
7
8
9
// setStrictMode(true) 启用严格模式后:
Bus.getDefault().post(new StringBuilder("Event"));

// 只有 onEvent1 能收到事件
public void onEvent1(StringBuilder event)
public void onEvent2(Object event)public void onEvent3(CharSequence event)
public void onEvent4(Serializable event)
public void onEvent5(Exception event)
public void onEvent6(String event)

对于 post(event)onEvent(EventType) ,严格模式的匹配规则是当且仅当 event.getClass().equals(EventType) 时才能收到事件。

说明:启用严格模式效率会稍微高一点,因为不会递归查找 event 的父类和实现的接口,但是由于 Bus 内部使用了缓存,对于同一个事件类型,并不会重复查找,所以实际使用几乎没有差别。

StickyEvent

可以使用下面的方法发送 Sticky 事件,这种事件会保留在内存中,当下一个注册者注册时,会立即收到上一次发送的该类型事件,每种类型的事件只会保留一个, Sticky 事件使用严格匹配模式。

1
public <E> void postSticky(E event)

一般不需要使用 Sticky 事件,但在某些场景下可以用到,比如一个网络状态监听服务,会不断的发送网络状态信息,接受者一旦注册就可以立即收到一个事件,可以知道当前的网络状态。

@BusEvent

还有一个注解 @BusEvent 可用于标注某个类是事件类,这个像 @Override 注解一样,纯标注用,没有其它用途,没有运行时消耗。

实现教程

坚持原创技术分享,您的支持将鼓励我继续创作!