EventBus是使用十分廣泛的事件總線框架, 2.0到3.0的變化還是挺大的
今天準(zhǔn)備重構(gòu)代碼,關(guān)于解耦想到了用EventBus惫东,發(fā)現(xiàn)EventBus出了3.0的beta版屎鳍,使用方式略有區(qū)別谱净,特此記錄秽梅。如果不會用EventBus的,請參考教程估脆。
3.0與2.x的區(qū)別
主要區(qū)別在訂閱函數(shù)的不同
EventBus2.x中只暴露了四個(gè)方法供用戶調(diào)用较幌,分別是
- onEvent:該事件在哪個(gè)線程發(fā)布出來的驰怎,onEvent就會在這個(gè)線程中運(yùn)行滤灯,也就是說發(fā)布事件和接收事件線程在同一個(gè)線程。使用這個(gè)方法時(shí)扛伍,在onEvent方法中不能執(zhí)行耗時(shí)操作作媚,如果執(zhí)行耗時(shí)操作容易導(dǎo)致事件分發(fā)延遲。
- onEventMainThread:不論事件是在哪個(gè)線程中發(fā)布出來的栏饮,onEventMainThread都會在UI線程中執(zhí)行吧兔,接收事件就會在UI線程中運(yùn)行,這個(gè)在Android中是非常有用的袍嬉,因?yàn)樵贏ndroid中只能在UI線程中跟新UI境蔼,所以在onEvnetMainThread方法中是不能執(zhí)行耗時(shí)操作的。
- onEventBackgroundThread:如果事件是在UI線程中發(fā)布出來的伺通,那么onEventBackground就會在子線程中運(yùn)行箍土,如果事件本來就是子線程中發(fā)布出來的,那么onEventBackground函數(shù)直接在該子線程中執(zhí)行罐监。
- onEventAsync:無論事件在哪個(gè)線程發(fā)布吴藻,都會創(chuàng)建新的子線程在執(zhí)行onEventAsync.
EventBus3.0中必須使用注解,例如:
@Subscribe(threadMode = ThreadMode.Async, sticky = true, priority = 1)
public void firstEvent(FirstEvent event) {
Log.e("TAG", "Async" + Thread.currentThread().getName());
}
好處在于訂閱函數(shù)可以隨便起名字弓柱,其他與2.x沒什么不同沟堡。
這里Subscribe中的key需要解釋一下含義,Subscribe中可以傳三種值:
-
ThreadMode:這是個(gè)枚舉矢空,有四個(gè)值航罗,決定訂閱函數(shù)在哪個(gè)線程執(zhí)行
- PostThread:事件發(fā)送者在哪個(gè)線程就執(zhí)行在哪個(gè)線程。同2.x中的onEvent方法妇多,默認(rèn)值就是這個(gè)
- MainThread:訂閱函數(shù)一定執(zhí)行在主線程伤哺。同onEventMainThread方法
- BackgroundThread:如果是事件從子線程發(fā)出,訂閱函數(shù)就執(zhí)行在那個(gè)子線程者祖,不會創(chuàng)建新的子線程立莉;如果主線程發(fā)出事件,則創(chuàng)建子線程七问。同onEventBackgroundThread方法
- Async:一定創(chuàng)建子線程蜓耻。同onEventAsync方法。
sticky:默認(rèn)為false械巡,如果為true刹淌,當(dāng)通過
postSticky
發(fā)送一個(gè)事件時(shí)饶氏,這個(gè)類型的事件的最后一次事件會被緩存起來,當(dāng)有訂閱者注冊時(shí)有勾,會把之前緩存起來的這個(gè)事件直接發(fā)送給它疹启。使用在比如事件發(fā)送者先啟動(dòng)了,訂閱者還沒啟動(dòng)的情況蔼卡。priority:默認(rèn)值為0喊崖。訂閱了同一個(gè)事件的訂閱函數(shù),在ThreadMode值相同的前提下雇逞,收到事件的優(yōu)先級荤懂。
具體使用
創(chuàng)建事件:
public class FirstEvent {
private String msg;
public FirstEvent(String msg){
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
在MainActivity的onCreate方法中注冊,onDestroy方法中反注冊
EventBus.getDefault().register(this);
EventBus.getDefault().unregister(this);
訂閱函數(shù)塘砸,此處用來查看執(zhí)行在哪個(gè)線程(注意节仿,這里的函數(shù)名可以任取):
@Subscribe(threadMode = ThreadMode.Async, sticky = true, priority = 1)
public void onAsync(FirstEvent event) {
Log.e("TAG", "Async: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.BackgroundThread)
public void onBackgroundThread(FirstEvent event) {
Log.e("TAG", "BackgroundThread: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.MainThread)
public void onMainThread(FirstEvent event) {
Log.e("TAG", "MainThread: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.PostThread)
public void onPostThread(FirstEvent event) {
Log.e("TAG", "PostThread: " + Thread.currentThread().getName());
}
在SecondActivity發(fā)送事件(主線程中發(fā)送):
EventBus.getDefault().post(new FirstEvent("啦啦啦"));
執(zhí)行結(jié)果如下:
Async: pool-1-thread-1
MainThread: main
PostThread: main
BackgroundThread: pool-1-thread-2
如果是在子線程中發(fā)送:
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new FirstEvent("啦啦啦"));
}
}).start();
執(zhí)行結(jié)果如下:
BackgroundThread: Thread-450
PostThread: Thread-450
Async: pool-1-thread-1
MainThread: main
如果先啟動(dòng)SecondActivity掉蔬,后啟動(dòng)MainActivity:
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new FirstEvent("啦啦啦"));
startActivity(new Intent(SecondActivity.this,MainActivity.class));
}
確實(shí)只有onAsync方法收到了消息廊宪。
至此對EventBus的試驗(yàn)基本就結(jié)束了,各位可以自行選擇不同的ThreadMode值眉踱,讓訂閱函數(shù)執(zhí)行在不同的線程挤忙。根據(jù)需要選擇是否需要sticky=true。
完整的MainActivity和SecondActivity代碼如下(xml文件就不貼了谈喳,就一個(gè)Button):
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,
SecondActivity.class));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.Async, sticky = true, priority = 1)
public void onAsync(FirstEvent event) {
Log.e("TAG", "Async: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.BackgroundThread)
public void onBackgroundThread(FirstEvent event) {
Log.e("TAG", "BackgroundThread: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.MainThread)
public void onMainThread(FirstEvent event) {
Log.e("TAG", "MainThread: " + Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.PostThread)
public void onPostThread(FirstEvent event) {
Log.e("TAG", "PostThread: " + Thread.currentThread().getName());
}
}
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
findViewById(R.id.second).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new FirstEvent("Lai自星星的我"));
startActivity(new Intent(SecondActivity.this,MainActivity.class));
}
});
}
}
參考鏈接
EventBus所有版本的Marven倉庫
EventBus2.x使用教程
快速Android開發(fā)系列通信篇之EventBus