说明
EventBus相信大家不会陌生,它可以极大的简化组件之间的通信,组件和后台线程之间的通信,今天我们来使用一下
我们模拟这样一个需求,在项目中也有可能用到的
一个注册的界面,需要下一步,下一步,最后注册成功将数据提交然后又返回到了主界面
我们这里简单使用一下,Activity之间传递信息就省略了,我们就模拟一下finish多个Activity的情景
还记得郭神的第一行代码中是如何finish多个Activity的吧,
自定义一个ActivityCollector类,把所有Activity的都add到一个List,然后for循环finish它们。
实践
那我们今天换一种方式,简单使用一下EventBus:
1、添加依赖
compile 'org.greenrobot:eventbus:3.0.0'
2、自定义一个类,可以是空类,因为我们不需要传递一个数据,只是去finish这个Activity,比如:
public class ActivityFinishEvent {
}
还是为了传递一个finish成功的消息,给他加一个message的属性
public class ActivityFinishEvent {
private String message;
public ActivityFinishEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3、在接收消息的Activity的onCreate()方法当中注册
EventBus.getDefault().register(this);
4、同时也一并把解除注册写到onDestroy当中,防止内存泄漏
EventBus.getDefault().unregister(this);
5、接收消息的方法实现
在EventBus3.0中,声明一个订阅方法需要用到@Subscribe注解,方法名可以自定义,但是必须是public
MainActivity:
//订阅方法,当接收到事件的时候,会调用该方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(ActivityFinishEvent event){
textView.setText(event.getMessage());
Toast.makeText(MainActivity.this, event.getMessage(), Toast.LENGTH_SHORT).show();
}
中间的其他Activity:
//订阅方法,当接收到事件的时候,会调用该方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(ActivityFinishEvent event){
finish();
}
6、发送事件
EventBus.getDefault().post(new ActivityFinishEvent("finish所有Activity,返回到主界面"));
发送事件在最后一个Activity中的Button的点击事件当中进行的,所有代码如下:
public class Main4Activity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getDefault().post(new ActivityFinishEvent("finish所有Activity,返回到主界面"));
finish();
}
});
}
}
至此,就完成了一次EventBus的简单使用。
理解
写完一个简单的例子后,我们再加深一下EventBus的理解,EventBus是观察者模式一个很好的实践:
一、EventBus三要素:
Event:事件,可以是任意类型的对象
Subscriber:事件订阅者,相当于我们在Activity中接受事件的方法, 在EventBus3.0前,只限定于onEvent、onEventMainThread、onEventBackground、onEventAsync,在EventBus3.0后,我们可以随便取名,但是需要添加个注解@Subscribe,然后去指定线程模型。
Publisher:事件发布者,可以在任意线程任意位置发送事件,根据post的参数类型,调用订阅相关类型事件的方法。
二、EventBus的四种线程模型(ThreadMode):
1、POSTING(默认):发布事件和接收事件在同一线程,避免执行耗时操作,否则会ANR
2、MAIN:事件的处理在主线程、也就是UI线程,事件处理时间不能太长,否则会ANR
3、BACKGROUND:事件在UI线程发布出来,接收事件会在新的子线程中执行,事件在子线程发布出来,接收事件就在这个子线程中执行,此方法中禁止进行UI操作
4、ASYNC:无论在哪个线程发布事件,接受事件都会在新建的一个子线程中执行,同样禁止进行UI操作
粘性事件:粘性事件发布后会存在内存中,比如说我已经new了2个fragment,post发送了事件之后, 这两个Fragment可以接受到这个事件,但是我再new2个出来,接受不到了,还得重新发送,粘性事件发布后存在内存中,我再new两个Fragment出来,一看之前有这个事件,直接匹配,不用重新发送事件了。使用的话直接在注解那一行加个sticky = true;
那我们再总结一下吧,
1、EventBus接收消息是根据传入的参数来判定的,所以我们可以发送多个事件,只要在接收事件的Activity中添加订阅方法,就可以接受到事件,比如:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(FirstEvent event){
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(SecondEvent event){
}
发送的时候:
EventBus.getDefault().post(new FirstEvent());
EventBus.getDefault().post(new SecondEvent());
2、如果添加了多个参数一样的订阅方法,但他们的ThreadMode不同,也是会接收到消息的
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(FirstEvent event){
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onEvent(FirstEvent event){
}
小Demo地址:EventBus小Demo
总结
EventBus的使用基本掌握,如果在项目中有用到的话,更会加深记忆。
这里用一个小例子熟悉了一下EventBus,记录一下,方便同学们查阅。