由greenrobot組織貢獻(該組織還貢獻了greenDAO),一個Android事件發布/訂閱輕量級框架,
功能:通過解耦發布者和訂閱者簡化Android事件傳遞
EventBus可以代替Android傳統的Intent,Handler,Broadcast或接口函式,在Fragment,Activity,Service執行緒之間傳遞數據,執行方法。
特點:代碼簡潔,是一種發布訂閱設計模式(觀察者設計模式)。
EventBus源碼下載
基本介紹
- 中文名:事件巴士
- 外文名:EventBus
- 是否開源:是
- 適用平台:android
- 作者:greenrobot組織
- 作用:簡化Android事件傳遞
使用場景,優勢,原理圖,基本使用,黏性事件使用,
使用場景
- 用於執行緒間的通訊代替handler或用於組件間的通訊代替Intent
- 廣泛用於團購,商城,社交等套用,比如易大師APP,易宸鋒Application...
- 實踐證明已經有一億多的APP中集成了EventBus
優勢
- 簡化了組件間的通訊。
- 分離了事件的傳送者和接受者。
- 在Activity、Fragment和執行緒中表現良好。
- 避免了複雜的和易錯的依賴關係和生命周期問題。
- 使得代碼更簡潔,性能更好。
- 更快,更小(約50k的jar包)。
原理圖
- EventBus底層採用的是註解和反射的方式來獲取訂閱方法信息(首先是註解獲取,若註解獲取不到,再用反射)
- 當前訂閱者是添加到Eventbus 總的事件訂閱者的subscriptionByEventType集合中
- 訂閱者所有訂閱的事件類型添加到typeBySubscriber 中,方便解註冊時,移除事件
提示:反射比註解更消耗資源且效率低
基本使用
(一)關聯EventBus框架
選中你所要關聯的Modules,點擊Dependencies,在點擊+號,選擇library dependency
在輸入框中輸入eventbus,選擇greenrobot公司提供的,進行關聯,新建一個Activity(EventBusSendActivity)
(二)在OnCreate註冊,在OnDestroy解除註冊
提示參數是上下文(你的事件在哪接收,就在哪個類進行EventBus的註冊和解除操作.)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //1. 註冊EventBus,參數是上下文. 注意:導入的EventBus請認準org.greenrobot. //注意:有註冊就必須有解註冊(一般在OnDestroy里執行解註冊操作),防止記憶體泄漏,註冊一個界面只能註冊一次,否則報錯 //關於源碼我只強調一點:EventBus拿到訂閱方法,無法兩種手段:1註解 2:反射 EventBus.getDefault().register(MainActivity.this); } @Override protected void onDestroy() { EventBus .getDefault().unregister(MainActivity.this); super.onDestroy(); }
(三)創建EventBus訊息類,設定屬性。
提示:EventBus訊息類,一個容器,負責存放一些數據,方便另一個訂閱者(接受者),獲取訊息
public class EventBusMessage { //定義了傳送的訊息必須是String. public String Message; public EventBusMessage(String message) { Message = message; } }
(四)使用EventBus的Post方法傳送事件
//4. 使用EventBus傳送事件,使用Post方法,參數也必須是EventBus訊息對且要和接收的保持一致 EventBus.getDefault().post(new EventBusMessage("易宸鋒,易大師好帥"));
(五)根據訊息類,接收事件
/*5接收訊息,參數就是你定義的EventBus訊息類,和傳送訊息類必須是同一個
加註解提示:在寫接收訊息的方法是,方法名可以自定義,許可權必須是public, 參數必須是一個只要接收的參數類型是一致的,那么四個方法都可以接收到傳送的信息 注釋:給人看 註解:給機器看 ThreadMode.MAIN表示這個方法在主執行緒中執行(適合做異步載入,可以將子執行緒載入到數據直接設定到UI界面里)*/ @Subscribe(threadMode = ThreadMode.MAIN) public void MessageEventBus(EventBusMessage eventBusMessage){ //在TextView顯示接收的訊息,從這個類里拿屬性. tv_title.setText(eventBusMessage.Message); Log.d("eventBusThread","ThreadMode.MAIN "+Thread.currentThread().getName()); } //ThreadMode.POSTING表示該方法和訊息傳送方在同一個執行緒. @Subscribe(threadMode = ThreadMode.POSTING) public void MessageEventBus1(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.POSTING "+Thread.currentThread().getName()); } /*ThreadMode.ASYNC也表示在後台執行(也就是子執行緒執行),可以異步並發處理 (適用於多個執行緒任務處理,內部有執行緒池管理,比如請求網路時,用這個方法,他會自動創建執行緒去請求) 無論發布者是在子執行緒還是主執行緒,該方法都會創建一個子執行緒,在子執行緒執行.*/ @Subscribe(threadMode = ThreadMode.ASYNC) public void MessageEventBus2(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.ASYNC "+Thread.currentThread().getName()); } //ThreadMode.BACKGROUND表示該方法在後台運行(也就是子執行緒),不能夠並發處理 //如果發布者在子執行緒,那么該方法就在子執行緒執行 //如果發布者在主執行緒,那么該方法就會創建一個子執行緒,在子執行緒運行. @Subscribe(threadMode = ThreadMode.BACKGROUND) public void MessageEventBus3(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.BACKGROUND "+Thread.currentThread().getName()); }
通過控制台所列印出來的執行緒名,總結一下輸出數據:
在主執行緒傳送事件 在子執行緒傳送事件
main: 主執行緒 主執行緒
posting: 主執行緒 子執行緒
background: 新開一個子執行緒 子執行緒
async: 新開一個子執行緒 新開一個子執行緒
黏性事件使用
概念:黏性事件就是指在EventBus內部被快取的那些事件
原理:EventBus為每個類(class)類型保存了最近一次被傳送的事件——sticky。後續被傳送過來的相同類型的sticky事件會自動替換之前快取的事件。當一個監聽者向EventBus進行註冊時,它會去請求快取事件。這時,快取的事件就會立即自動傳送給這個監聽者,有一定的延時性.
使用場景:Android上跨Activity和Fragment生命周期傳遞數據這種複雜問題,異步調用等等
EventBus的黏性使用方法:(EventBus的環境搭建和EventBus基本使用是一致的)
(一)創建EventBus訊息類,設定屬性
提示:EventBus訊息類,一個容器,負責存放一些數據,方便另一個訂閱者(接受者),獲取訊息
public class EventBusStickyMessage { public String message; public EventBusStickyMessage(String message) { this.message = message; } }
(二)傳送黏性事件到接收頁面
public void send(View view){ EventBus.getDefault().postSticky(new EventBusStickyMessage("易大師,YiChenFeng好帥")); //跳轉到傳送頁面的界面 Intent intent1 = new Intent(MainActivity.this, EventBusReceiveActivity.class); startActivity(intent1); }
(三)接收黏性事件
提示:多了一個屬性Sticky,改為true方是啟動黏性事件
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) public void EventBusSticky(EventBusStickyMessage eventBusStickyMessage){ tv_title.setText(eventBusStickyMessage.message); }
(四)根據點擊事件,得到黏性事件
//做個標記,以防EventBus會進行多次註冊boolean flag=true; @Overridepublic void onClick(View v) { //接收黏性數據,實際就是補上註冊的環節,容易迷,所以要用心看,注意你一旦註冊eventBus就會接收到訊息 if(flag){ //D. EventBus註冊廣播(),參數是上下文. 導入的EventBus請認準org.greenrobot //注意:有註冊就必須有解註冊(一般在OnDestroy里執行解註冊操作),防止記憶體泄漏,註冊一個界面只能註冊一次,否則報錯 EventBus.getDefault().register(this); //更改標記,使其不會再進行註冊,多次註冊會報錯 flag=false; } }
(五)在onDestroy里解除EventBus註冊
// 注意:這裡比普通的解除註冊還多一步,就是移除黏性事件(是移除所有的還是移除一個,看需求) @Overrideprotected void onDestroy() { //移除所有的黏性事件 EventBus.getDefault().removeAllStickyEvents(); //解除註冊 EventBus .getDefault().unregister(this); super.onDestroy(); }