簡介
EventBus是一個Android事件發(fā)布/訂閱框架鹦马,通過解耦發(fā)布者和訂閱者簡化Android事件傳遞鳄虱,這里的事件可以理解為消息。EventBus 3.0中EventBus提供了EventBusAnnotationProcessor注解處理器來在編譯期通過讀取@Subscribe()注解并解析、處理其中所包含的信息,然后生成java類來保存所有訂閱者關(guān)于訂閱的信息赡茸,這樣就比在EventBus 2.x 采用反射的方式對整個注冊的類的所有方法進行掃描來完成注冊的速度要快
使用
首先添加引用 compile 'org.greenrobot:eventbus:3.0.0'
EventBus的主要元素
- Event :事件,可以是任意類型的對象祝闻。
- Publisher:事件發(fā)布者占卧,用于通知Subscriber有事件發(fā)生
- Subscriber :事件訂閱者,接收特定的事件
-
ThreadMode :定義函數(shù)在何種線程中執(zhí)行联喘,主要包含四個ThreadMode
- ThreadMode.POSTING: 事件的處理在和事件的發(fā)送在相同的進程屉栓,所以事件處理時間不應(yīng)太長,不然影響事件的發(fā)送線程耸袜,而這個線程可能是UI線程友多。
- ThreadMode.MAIN: 事件的處理會在UI線程中執(zhí)行。事件處理時間不能太長堤框,這個不用說的域滥,長了會ANR的。
- ThreadMode.BACKGROUND: 事件的處理會在一個后臺線程中執(zhí)行,但事件處理時間還是不應(yīng)該太長蜈抓,因為如果發(fā)送事件的線程是后臺線程启绰,會直接執(zhí)行事件,如果當前線程是UI線程沟使,事件會被加到一個隊列中委可,由一個線程依次處理這些事件,如果某個事件處理時間太長腊嗡,會阻塞后面的事件的派發(fā)或處理着倾。
- ThreadMode.AYSNC: 事件處理會在單獨的線程中執(zhí)行,主要用于在后臺線程中執(zhí)行耗時操作燕少,每個事件會開啟一個線程(有線程池)卡者,但最好限制線程的數(shù)目。
使用的基本步驟
- 定義事件類型:
public class Event {}
- 定義事件處理方法:
public void onEvent
- 注冊訂閱者:
EventBus.getDefault().register(this)
- 發(fā)送事件:
EventBus.getDefault().post(new Event())
- 取消注冊:
EventBus.getDefault().unregister(this)
如下一個使用例子
- 定義一個事件類型
public class Event {
private String message;
public Event(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
- 處理事件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注冊
EventBus.getDefault().register(this);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
Log.e("lwd", "hahha");
startActivity(intent);
}
});
}
/**
* 在這里處理事件
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 100)//在ui線程執(zhí)行 優(yōu)先級100
public void onEvent(Event event) {
String msg = event.getMessage();
((TextView) findViewById(R.id.tv)).setText(msg);
}
@Override
protected void onDestroy() {
super.onDestroy();
//反注冊
EventBus.getDefault().unregister(this);
}
}
優(yōu)先級越高優(yōu)先獲得消息,優(yōu)先級高的訂閱者可以終止事件往下傳遞
EventBus.getDefault().cancelEventDelivery(event) ;
其中sticky=true
表示黏性事件客们,為了方便理解成訂閱在發(fā)布事件之后崇决,但同樣可以收到事件。發(fā)送粘性事件EventBus.getDefault().postSticky(new Event());
如果不再需要該粘性事件我們可以移除EventBus.getDefault().removeStickyEvent(new DataSynEvent());
底挫,或者調(diào)用移除所有粘性事件EventBus.getDefault().removeAllStickyEvents();
- 發(fā)送事件
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new Event("hahahaha"));
}
}).start();
}
});
}
}
調(diào)用不同的訂閱函數(shù)
首先建立四個類:FirstEvent恒傻、SecondEvent、ThirdEvent 建邓、FourthEvent盈厘。
public class FirstEvent {
private String message;
public FirstEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class SecondEvent{
private String message;
public SecondEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class ThirdEvent{
private String message;
public ThirdEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class FourthEvent{
private String message;
public FourthEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
然后在MainActivity中,增加四種模式的訂閱函數(shù)
/**
* 在這里處理事件
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN, priority = 100)
public void onEventMain(FirstEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.BACKGROUND, priority = 100)
public void onEventBackground(SecondEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)
public void onEventPosting(ThirdEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.ASYNC, priority = 100)
public void onEventAsync(FourthEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
接下來在SecondActivity中增加四個按鈕涝缝,分別發(fā)送不同類別的事件
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new FirstEvent("我是1"));
}
}).start();
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new SecondEvent("我是2"));
}
}).start();
}
});
findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new ThirdEvent("我是3"));
}
}).start();
}
});
findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new FourthEvent("我是4"));
}
}).start();
}
});
分別順序點擊SecondActivity的四個按鈕扑庞,打印信息如下:
10-18 11:18:47.723 10159-10159/com.example.luoweidong.eventbu E/lwd: 我是1
10-18 11:18:48.763 10159-10262/com.example.luoweidong.eventbu E/lwd: 我是2
10-18 11:18:49.863 10159-10281/com.example.luoweidong.eventbu E/lwd: 我是3
10-18 11:18:50.403 10159-10294/com.example.luoweidong.eventbu E/lwd: 我是4
由此可見譬重,通過發(fā)布不同的事件類的實例拒逮,EventBus根據(jù)類的實例分別調(diào)用了不同的訂閱函數(shù)來處理事件罐氨。訂閱函數(shù)的執(zhí)行是根據(jù)參數(shù)中的事件類的類名來決定的。