Android開發學習之路-EventBus使用,android-eventbus

來源:互聯網
上載者:User

Android開發學習之路-EventBus使用,android-eventbus

EventBus是一個通過發布、訂閱事件實現組件間訊息傳遞的工具。

它存在的目的,就是為了最佳化組件之間傳遞訊息的過程。傳統組件之間傳遞訊息的方法有使用廣播,回調等,而這些方法使用都比較複雜。

工作原理:

依賴:

1 dependencies {2     compile 'org.greenrobot:eventbus:3.0.0'3 }

註:EventBus是事件-訂閱模型,實際上事件就是訊息,訂閱就是接收,本文不會很嚴格區分,方便理解為主!

1. 從簡單的入手:充當Handler

既然能發送訊息,那麼自然在同一個組件下也能進行訊息的發送和接收,也就是Handler的職責。

先定義一個事件的對象:

 1 public class MessageEvent { 2     private String message; 3  4     public MessageEvent(String message) { 5         this.message = message; 6     } 7  8     public String getMessage() { 9         return message;10     }11 12     @Override13     public String toString() {14         return message;15     }16 }

這個事件對象只需要是Object的子類,沒其他要求,訊息的內容可以隨意定,這裡用一個String表示事件的訊息,toString直接輸出事件的內容。

在需要接收訊息的組件中,進行EventBus的綁定,這裡由Activity充當訂閱者(Subscriber),也就是訊息接收者。

 1 public class MainActivity extends AppCompatActivity { 2  3     @Override 4     protected void onCreate(Bundle savedInstanceState) { 5         super.onCreate(savedInstanceState); 6         setContentView(R.layout.activity_main); 7     } 8  9     @Override10     protected void onStart() {11         super.onStart();12         EventBus.getDefault().register(this); // 將當前Activity綁定為訂閱者13     }14 15     @Override16     protected void onStop() {17         EventBus.getDefault().unregister(this); // 解除綁定18         super.onStop();19     }20 21     // 聲明一個訂閱者法,用於接收事件22     @Subscribe23     public void onEvent(MessageEvent messageEvent) {24         Log.d(TAG, "onEvent() called with: messageEvent = [" + messageEvent + "]");25     }26 27 }

通過EventBus.getDefault方法擷取到一個EventBus的一個單例,也就是每次調用這個方法得到的都是同一個EventBus對象。而不同的EventBus對象訊息不會互連。

接著需要在Activity的onStart方法中進行對EventBus對象的綁定,在onStop方法中進行解除綁定。同時,需要定義用於接收事件的方法,並加上@Subscribe註解表明該方法用於接收訂閱事件。

接著,我們需要發送事件:

1 EventBus.getDefault().post(new MessageEvent("I m Fndroid"));

這裡擷取的預設的EventBus對象,通過post方法進行事件的發送,log如下:

 

2. 組件間通訊:代替廣播、回調等

EventBus的存在,並不是為了替代Handler,而是用來進行組件間的通訊。有了上面的知識,接下來就不難了。

我們都知道,只要是同一個EventBus對象綁定的組件(Subscriber),訊息是互連的,也就是我們可以在Service中向Activity發送事件進行通訊。(其他組件類似)

定義一個IntentService,並且發送一個事件,而Activity,和上面一樣。

 1 public class MyIntentService extends IntentService { 2  3     public MyIntentService() { 4         super("MyIntentService"); 5     } 6  7     @Override 8     protected void onHandleIntent(Intent intent) { 9         EventBus.getDefault().post(new MessageEvent("From service"));10     }11 12 }

在Activity中開啟服務:

1 startService(new Intent(this, MyIntentService.class));

Log:

組件間的通訊變得如此簡單了。

 

3. 進階:持久事件、線程模式、優先順序

① 持久事件(StickyEvent):對於調用post方法發送的普通訊息,會在第一次被接收到的時候被消費掉,也就是我們在@Subscribe方法下處理完了,這個訊息就消失了。而EventBus則提供了另一種類型的訊息——StickyEvent,這個訊息,會被儲存在RAM中,直到下一個StickyEvent被發送才會被替換。每個EventBus對象都能通過geStickyEvent方法擷取最近發出的持久事件。

我們對Activity稍作修改,在訂閱者法中,把當前的持久訊息列印出來:

1     // 聲明一個訂閱者法,用於接收事件2     @Subscribe3     public void onEvent(MessageEvent messageEvent) {4         Log.d(TAG, "onEvent() called with: messageEvent = [" + messageEvent + "]");5         Log.d(TAG, "onEvent: Sticky Event = [" + EventBus.getDefault().getStickyEvent(MessageEvent.class) + "]");6     }

接著對Service也進行修改,令其發送一個StickyEvent:

1     @Override2     protected void onHandleIntent(Intent intent) {3         EventBus.getDefault().post(new MessageEvent("From service"));4         EventBus.getDefault().postSticky(new MessageEvent("From service2"));5         EventBus.getDefault().post(new MessageEvent("From service3"));6     }

這裡看到,在第二次發送的時候,調用了postSticky方法發送事件,這就表明了該事件是一個持久事件,除非有新的同類型(不同類型的事件可以共存)持久事件被發送,否則會一直被儲存在記憶體中,我們任何時候都能擷取得到。

Log:

可以看到,在第三次接收到訊息的時候,將StickyEvent列印出來,依舊是"From service2"。

同樣的,如果我們想要移除此持久事件,可以調用EventBus的removeStickyEvent方法來實現,如果要移除所有類型的持久事件,可以調用removeAllStickyEvent方法。

② 線程模式

EventBus允許我們對訂閱者進行線程設定,預設情況下,訂閱是和事件發送處於同一線程的,我們不妨把訂閱的線程id列印出來看一看。

修改Activity中的@Subscribe方法:

1     @Subscribe2     public void onEvent(MessageEvent messageEvent) {3         Log.d(TAG, "onEvent: Thread id = [" + Thread.currentThread().getId() + "]");4         Log.d(TAG, "onEvent() called with: messageEvent = [" + messageEvent + "]");5     }

修改Service,讓其發送一次普通事件,並且輸出當前線程id:

1     @Override2     protected void onHandleIntent(Intent intent) {3         Log.d(TAG, "onHandleIntent: Thread id = [" + Thread.currentThread().getId() + "]");4         EventBus.getDefault().post(new MessageEvent("From service"));5     }

列印Log:

對於訂閱者,有以下四種線程模式:

設定訂閱者線程很簡單,只需要在註解中賦值即可,如:

1     @Subscribe(threadMode = ThreadMode.MAIN)

③ 優先順序

每個組件中可以有多個訂閱者法,而我們可以對它們設定不同的優先順序,設定的方法也很簡單:

1     @Subscribe(priority = 88)

預設的優先順序為0,更高優先順序的訂閱者法會更先收到事件,而每個訂閱者法都可以對事件進行終止,可以通過以下方法停止事件傳遞:

1    EventBus.getDefault().cancelEventDelivery(messageEvent);

④ 自訂EventBus對象

通過getDefault方法擷取的是一個EventBus預設的單例,而我們可以通過EventBus.Builder來構造一個自訂的EventBus對象。

 

明白了用法以後,我們分析源碼也會更加簡單。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.