简洁的 EventBus 实现:Android xBus

jopen 9年前

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

使用指南

Gradle 集成

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

接收事件

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或某个线程里,可以在任何地方发送事件:

// 比如在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/Service的onCreate/onDestroy方法里,register()和unregister()建议配对使用,避免内存泄露。

 @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对象:

public class MainApp extends Application {      private Bus mBus = new Bus();      @Override      public void onCreate() {          super.onCreate();      }      public Bus getBus() {          return mBus;      }  }

Debug

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

public Bus setDebug(final boolean debug)

MethodFinder

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

public Bus setMethodFinder(final MethodFinder finder)

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

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

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

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

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

StrictMode

宽泛匹配模式

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

// 如果你调用这个方法,发送一个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,那么匹配成功,能收到事件。

严格匹配模式

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

public Bus setStrictMode(final boolean strictMode)

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

// 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事件使用严格匹配模式。

public <E> void postSticky(E event)

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

@BusEvent

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

实现教程

项目主页:http://www.open-open.com/lib/view/home/1440248130395