Android,android官網
EventBus
EventBus是一個Android端最佳化的publish/subscribe訊息匯流排,簡化了應用程式內各組件間、組件與後台線程間的通訊。比如請求網路,等網路返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通訊,這些需求都可以通過EventBus實現。
作為一個訊息匯流排,有三個主要的元素:
- Event:事件
- Subscriber:事件訂閱者,接收特定的事件
- 在EventBus中,使用約定來指定事件訂閱者以簡化使用。即所有事件訂閱都都是以onEvent開頭的函數,具體來說,函數的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync這四個,這個和ThreadMode有關。
- Publisher:事件發行者,用於通知Subscriber有事件發生
- 可以在任意線程任意位置發送事件,直接調用EventBus的`post(Object)`方法,可以自己執行個體化EventBus對象,但一般使用預設的單例就好了:`EventBus.getDefault()`,根據post函數參數的類型,會自動調用訂閱相應類型事件的函數。
ThreadMode
每個事件訂閱函數都是和一個`ThreadMode`相關聯的,ThreadMode指定了會調用的函數。有以下四個ThreadMode:
- PostThread:事件的處理在和事件的發送在相同的進程,所以事件處理時間不應太長,不然影響事件的發送線程,而這個線程可能是UI線程。對應的函數名是onEvent。
- MainThread: 事件的處理會在UI線程中執行。事件處理時間不能太長,這個不用說的,長了會ANR的,對應的函數名是onEventMainThread。
- BackgroundThread:事件的處理會在一個後台線程中執行,對應的函數名是onEventBackgroundThread,雖然名字是BackgroundThread,事件處理是在後台線程,但事件處理時間還是不應該太長,因為如果發送事件的線程是後台線程,會直接執行事件,如果當前線程是UI線程,事件會被加到一個隊列中,由一個線程依次處理這些事件,如果某個事件處理時間太長,會阻塞後面的事件的派發或處理。
- Async:事件處理會在單獨的線程中執行,主要用於在後台線程中執行耗時操作,每個事件會開啟一個線程(有線程池),但最好限制線程的數目。
根據事件訂閱都函數名稱的不同,會使用不同的ThreadMode,比如果在後台線程載入了資料想在UI線程顯示,訂閱者只需把函數命名為onEventMainThread。
使用流程
定義事件類型:
public class MyEvent {}
定義事件處理方法:
public void onEventMainThread
註冊訂閱者:
EventBus.getDefault().register(this)
發送事件:
EventBus.getDefault().post(new MyEvent())
Sample
public class MainActivity extends ActionBarActivity { private ConditionVariable mConditionVariable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mConditionVariable = new ConditionVariable(); EventBus.getDefault().register(this); initUI(); startActivity(new Intent(this, TwoActivity.class)); new Thread(new SleepThread()).start(); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } TextView mTxtOne; private void initUI() { mTxtOne = (TextView) findViewById(R.id.txt_one); } public void onEventMainThread(EventOne eventOne) { Log.i("MainActivity", "MainActivity,,,onEventMainThread"); mTxtOne.setText(eventOne.getString()); }// public void onEventAsync(EventOne eventOne) {// Log.i("MainActivity", "onEventAsyc--->" + Thread.currentThread().getName());// }//// public void onEventBackgroundThread(EventOne eventOne) {// Log.i("MainActivity", "onEventBackgroundThread--->" + Thread.currentThread().getName());// }// public void onEventPostThread(EventOne eventOne) {// Log.i("MainActivity", "onEventPostThread--->" + Thread.currentThread().getName());// } class SleepThread implements Runnable { @Override public void run() { Log.i("Activity", "MainActivity,,,SleepThread--->begin"); mConditionVariable.block(2000); Log.i("Activity", "MainActivity,,,SleepThread--->end"); EventBus.getDefault().post(new EventOne("11111")); } }}
EventOne代碼:
public class EventOne { String string; public EventOne(String string) { this.string = string; } public String getString() { return string; }}