</div> </div>
现在Event Bus会把所有的LocationChangedEvent 事件都发送给上面的函数。MmLocationManager 类不用注册监听器了,当位置改变的时候 只需要向Event Bus发布事件即可:
bus.post(new LocationChangedEvent(37.892818, -121.772608));
这样 组件间相互解耦了,而单元测试也变得简单了。任何事件都可以发布给Event Bus,然后Event Bus会找到对该事件感兴趣的函数来调用。
注意:您也许已经发现该模式在Android上层也存在 — Intent系统就是这样设计的!
Android系统的Event Bus模式类库
1、Otto — Android系统的Event Bus类库
Otto是Square公司在他们应用中使用的Event Bus实现。从Guava中演变而来,并且专注于Android平台。
通过使用Otto,Square公司的应用组件间不紧密耦合了,单元测试也更加容易了。
Otto项目的主页:http://square.github.io/otto/
Otto项目GitHub地址:https://github.com/square/otto
2、EventBus — Android系统的Event Bus类库
EventBus 是http://greenrobot.de 出品的另外一个Event Bus类库,功能稍微多一点。
EventBus 项目地址:https://github.com/greenrobot/EventBus
关于两者的对比可以参考EventBus 项目Comparison with Square's Otto部分: https://github.com/greenrobot/EventBus#comparison-with-squares-otto
EventBus介绍
EventBus可以向不同的线程中发布事件,在ThreadMode 枚举中定义了4个线程,只需要在事件响应函数名称“onEvent”后面添加对应的线程类型名称,则还事件响应函数就会在对应的线程中执行,比如事件函数 “onEventAsync”就会在另外一个异步线程中执行,ThreadMode定义的4个线程类型如下:
PostThread:事件响应函数和事件发布在同一线程中执行。这个是默认值,这样可以避免线程切换。
MainThread:事件响应函数会在Android应用的主线程(大部分情况下都是UI线程)中执行。
BackgroundThread:事件响应函数会在一个后台线程中执行。如果事件发布函数不是在主线程中,则会立即在事件发布线程中执行响应函数。如果事件发布函数在主线程中,EventBus则会在唯一的一个后台线程中按照顺序来执行所有的后台事件响应函数。
上面的3种事件响应函数,应该能够很快的执行完,不然的话会阻塞各自的事件发布。
async:事件响应函数在另外一个异步线程中执行。该线程和发布线程、主线程相互独立。如果事件响应函数需要较长的时间来执行,则应该使用该模式,例如 网络访问等。需要注意的是,由于系统并行的限制,应该避免在同一时间触发大量的异步线程。
在Android中我们可以在onCreate方法中调用EventBus的register(Object subscriber) 注册订阅者:
</div> </div>
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); EventBus.getDefault().register(this); }
调用EventBus的unregister(Object subscriber) 方法 取消注册的订阅者:
</div> </div>
@Override protected void onDestroy() { super.onDestroy(); try { EventBus.getDefault().unregister(this); } catch (Throwable t){ //this may crash if registration did not go through. just be safe } }
调用EventBus的post(Object event) 方法 post消息到Bus上,本例是在一个子线程中post一个消息到UI线程:
</div> </div>
@Override public void onRun() throws Throwable { // TODO Auto-generated method stub Log.e(TAG, "onRun sleep 6s"); Thread.sleep(6000); EventBus.getDefault().post(new PostedCityEvent("posted")); }
在订阅者中实现的 EventBus 上的事件处理方法,本例是在Activity中进行处理的: