EventBus 直译过来就是事件总线,它使用发布订阅模式支持组件之间的通讯,不须要显式地注册回调,比观察者模式更灵活,可用于替换Java中传统的事件监听模式,EventBus的做用就是解耦,它不是通用的发布订阅系统,也不能用于进程间通讯。可用于Android的EventBus库主要有这几个:Google出品的Guava,Guava是一个庞大的库,EventBus 只是它附带的一个小功能,所以实际项目中使用并很少。用的最多的是greenrobot/EventBus,这个库的优势是接口简洁,集成方便,可是限定了方法名,不支持注解。另外一个库square/otto修改自 Guava ,用的人也很多。spring
以greenrobot/EventBus 为例,咱们看一下 EventBus 模式的典型用法:缓存
// 注册EventBus,接受事件 class Fragment { public void onCreate(){ EventBus.getDefault().register(this); } public void onDestroy(){ EventBus.getDefault().unregister(this); } public void onEvent(SomeEvent1 event){ // handle event } } // 处理任务,发送事件 public class Service { public void doSomeThing(){ // do your work // send event EventBus.getDefault().post(new SomeEvent1()); }
关于EventBus中的几个问题?app
1、Guava EventBus 观察者模式异步
首先,咱们声明一个Observer:post
public class EventObserver { @Subscribe public void onMessage(Message message) { ... } }
这个类并无继承任何接口,只是在用来响应通知的方法上声明了一个@Subscribe。ui
使用EventBus很简单,先声明一个:this
EventBus eventBus = new EventBus();
而后,把咱们写好的Observer注册进去:线程
eventBus.register(new EventObserver());
当要通知Observer时,咱们只要这样便可:设计
eventBus.post(message);
这里,咱们并无告诉EventBus,咱们要处理的是一个Message类型,只是在EventObserver的onMessage方法的接口声明上使用了这个类型而已。可是,当咱们把消息发送出去的时候,它会根据类型进行匹配,保证咱们的消息正确地发送到对应的地方。orm
相比于JDK原有的实现,这个实现会更简单。EventObserver再也不须要存在一个继承体系中,而继承老是一种枷锁,把咱们套牢在一个体系之中:
这种变换让静态类型的Java语言,有了一些动态类型的特质,也让程序更加灵活。这种灵活性多半要归功于Annotation,它在很大程度上影响了Java的程序设计风格。
除了标准的EventBus,Guava还提供了另一个AsyncEventBus,从名字就能够看出,这是一个异步的EventBus,也就是说,消息扔给它以后,会当即返回,至于Observer何时处理,那就是它的事情了。当处理耗时的处理时颇有用,咱们要依赖Executors来实现异步事件总线。
AsyncEventBus eventBus = new AsyncEventBus("test", Executors.newCachedThreadPool());
另外:关于EventBus的使用请参见:http://blog.mcxiaoke.com/2015/08/03/how-to-write-an-eventbus-part1/
2、示例
一、一个事件的定义(任何对象均可以是事件)
public class SignEvent { private String companyName; private String signName; private Date signDate; public SignEvent(String name,String signName, Date signDate) { super(); this.companyName = name; this.signName = signName; this.signDate = signDate; } public String getMessage(){ StringBuilder sb = new StringBuilder(); sb.append("物流公司:").append(this.companyName); sb.append("签收人:").append(signName).append(",签收日期:").append(signDate); return sb.toString(); } }
二、定义两个事件监听器,添加注解作事件的订阅
public class YTOEventListener { @Subscribe public void consign(SignEvent signEvent){ if(signEvent.getCompanyName().equalsIgnoreCase("YTO")){ System.out.println("YTO。。。开始发货"); System.out.println(signEvent.getMessage()); } } @Subscribe public void delivery(SignEvent signEvent){ if(signEvent.getCompanyName().equalsIgnoreCase("YTO")){ System.out.println("YTO。。。开始投递"); } } } public class SFEventListener { @Subscribe public void consign(SignEvent signEvent){ if(signEvent.getCompanyName().equalsIgnoreCase("SF")){ System.out.println("SF。。。开始发货"); System.out.println(signEvent.getMessage()); } } @Subscribe public void delivery(SignEvent signEvent){ if(signEvent.getCompanyName().equalsIgnoreCase("SF")){ System.out.println("SF。。。开始投递"); } } }
三、EventBus的例子,包含时间的注册以及事件的提交
public class EventBusTest { public static void siginalThreadConsumer(){ EventBus bus = new EventBus("iamzhongyong"); SFEventListener sf = new SFEventListener(); YTOEventListener yto = new YTOEventListener(); bus.register(sf); bus.register(yto); SignEvent sign1 = new SignEvent("SF","比熊啊",new Date()); bus.post(sign1); SignEvent sign2 = new SignEvent("YTO","你妹的",new Date()); bus.post(sign2); } public static void multiThread(){ EventBus bus = new AsyncEventBus(Executors.newFixedThreadPool(3)); SFEventListener sf = new SFEventListener(); YTOEventListener yto = new YTOEventListener(); bus.register(sf); bus.register(yto); SignEvent sign1 = new SignEvent("SF","比熊啊",new Date()); bus.post(sign1); SignEvent sign2 = new SignEvent("YTO","你妹的",new Date()); bus.post(sign2); } public static void main(String[] args) { EventBusTest.siginalThreadConsumer(); EventBusTest.multiThread(); } }