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(); } }