EventBus是一个事件发布/订阅总线,有效适用于Android系统平台。
配置
在build.gradle文件中添加EvnetBus依赖
compile 'org.greenrobot:eventbus:3.1.1'
在Activity的onCreate或Fragmnet的onViewCreated中注册EvnetBus
EventBus.getDefault().register(this);
在Activity或Fragmnet的onDestroy中取消注册EvnetBus
EventBus.getDefault().unregister(this);
通过post发送订阅事件
//发送普通事件
EventBus.getDefault().post(new SonEvent("China"));
//发送粘性事件
EventBus.getDefault().postSticky(new SonEvent("USA"));
提示
粘性事件与一般的事件不同,粘性事件是先发送出去,然后让后面注册的订阅者能够收到该事件。粘性事件的发送是通过postSticky方法进行发送
这里可以在上一个Activity中发送一个粘性事件,在MainActivity中接受
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送粘性事件
EventBus.getDefault().postSticky(new SonEvent("USA"));
}
});
使用
public class MainActivity extends AppCompatActivity {
private Button mBtn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity);
//订阅
EventBus.getDefault().register(this);
mBtn1 = (Button) findViewById(R.id.btn1);
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送事件
EventBus.getDefault().post(new SonEvent("china"));
}
});
}
@Override
protected void onStop() {
super.onStop();
//取消注册
EventBus.getDefault().unregister(this);
}
//不管发送在什么线程-这里只在主线程接受-阻塞式代码执行(订阅方法立即执行)
@Subscribe(threadMode = ThreadMode.MAIN)
public void sonEventMain(SonEvent evet) {
Log.d("message", "SonEvent-MAIN" + "--当前线程:" + Thread.currentThread());
}
//发送到主线-因FatherEvent是SonEvent的父类,所以也可以收到
@Subscribe(threadMode = ThreadMode.MAIN)
public void fatherEvent(FatherEvent evet) {
Log.d("message", "FatherEvent" + "--当前线程:" + Thread.currentThread());
}
//发送到主线-因SonEvent实现了PeopleEvent接口,所以也可以收到
@Subscribe(threadMode = ThreadMode.MAIN)
public void peopleEvent(PeopleEvent evet) {
Log.d("message", "PeopleEvent" + "--当前线程:" + Thread.currentThread());
}
//post在什么线程,这里接受就在什么线程
@Subscribe(threadMode = ThreadMode.POSTING)
public void sonEventPosting(SonEvent evet) {
Log.d("message", "sonEvent-POSTING" + "--当前线程:" + Thread.currentThread());
}
//不管发送在什么线程-这里只在主线程接受-非阻塞式(先进队列,订阅方法顺序执行)
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void sonEventMainOrdered(SonEvent evet) {
Log.d("message", "sonEvent-MAIN_ORDERED" + "--当前线程:" + Thread.currentThread());
}
//在后台(非主线程)执行(订阅方法顺序执行)
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void sonEventBackground(SonEvent evet) {
Log.d("message", "sonEvent-BACKGROUND" + "--当前线程:" + Thread.currentThread());
}
//在后台(非主线程)执行(订阅方法并行执行)
@Subscribe(threadMode = ThreadMode.ASYNC)
public void sonEventAsync(SonEvent evet) {
Log.d("message", "sonEvent-ASYNC" + "--当前线程:" + Thread.currentThread());
}
//发送粘性事件
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 100)
public void sonsticky(SonEvent event) {
Log.d("message", "sticky-" + "name:" + event.getName() + "--当前线程:" + Thread.currentThread());
}
}
打印结果
com.cn.liuyz.javademo D/message: sticky-name:USA--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: sticky-name:China--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: SonEvent-MAIN--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: sonEvent-POSTING--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: PeopleEvent--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: FatherEvent--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: sonEvent-ASYNC--当前线程:Thread[pool-1-thread-1,5,main]
com.cn.liuyz.javademo D/message: sonEvent-MAIN_ORDERED--当前线程:Thread[main,5,main]
com.cn.liuyz.javademo D/message: sonEvent-BACKGROUND--当前线程:Thread[pool-1-thread-2,5,main]
BACKGROUND和ASYNC区别
BACKGROUND中的任务是一个接着一个去调用,使用executorRunning布尔值进行控制(顺序执行)
Async中的任务会立即获取空闲线程或者直接创建线程去执行(并发执行)
两者都是使用Executors.newCachedThreadPool()创建线程池
总结
- 发布订阅事件时,不管订阅方法是否支持粘性,都可收到订阅事件
- 订阅方法优先级越高越快执行