前言
当我们进行开发的时候往往需要和各组件之间进行通信,主要功能是替Intent,Handler,BroadCastReceiver 在Fragment,Activity,Service,线程之间传递消息。当我们项目越来越大,越来越复杂的时候,Intent,Handler,BroadCastReceiver进行模块与后台线程通信时,代码量大,耦合度高,不容易代码维护,所以我们今天就来讲讲降低耦合度的EventBus3.0吧。
开源地址:https://github.com/greenrobot/EventBus
官方网站:http://greenrobot.org/eventbus/
官方文档:http://greenrobot.org/files/eventbus/javadoc/3.0/
添加依赖
implementation ‘org.greenrobot:eventbus:3.1.1’
关键词理解
- Subscriber 事件订阅者,在Event2.0的时候消息处理的方法只能有四种onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync他们分别代表四种线程模式,而在Event3.0之后接收消息的方法名可以任意定义,方法名上需要加注解@Subscribe,然后指定一种线程模式,POSTING为默认线程;
- Publisher 事件发布者,可以发送任意线程事件,并且可以是任意类型,EventBus.getDefault().post(Object);或者带粘性事件发布 EventBus.getDefault().postSticky(Object);
- 粘性事件 只指事件消费者在事件发布之后才注册的也能接收到该事件的特殊类型,通俗来讲就是,消息发出去了,第一个Activity收到了消息,如果第二个Activity也订阅了,也会收到。;
四种线程模式
- ThreadMode.Main 表示这个方法在主线程中执行(适合做异步加载,可以将子线程 加载到数据直接设置到 UI 界面),这个用的比较多;
- ThreadMode.Posting 表示该方法和消息发送方在同一个线程;
- ThreadMode.ASYNC 表示无论发送方是在子线程还是在主线程,都会开一个新的子线程去运行,适用于多个线程任务,内部有线程池管理,比如请求网络时,用这个方法,他会自动创建方法去请求,可以异步并发处理;
- ThreadMode.BackGround 表示该方法在后台运行(也就是子线程),不能够并发处理,如果发布者在子线程,那么该方法就在子线程执行。如果发布者在主线程,那么该方法就会创建一个子线程,在子线程运行;
EventBus3.0基本使用
注册事件
当我们需要在Activity或者Fragment里订阅事件时,我们需要注册EventBus。我们一般选择在Activity的onCreate()方法里去注册EventBus,在onDestory()方法里,去解除注册。
/**
* Created by 朱大大
* QQ:941556675
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
解除事件
注册了一定要记得解除哦
/**
* Created by 朱大大
* QQ:941556675
*/
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
实体类
/**
* Created by 朱大大
* QQ:941556675
*/
public class MessageEvent{
private String message;
public MessageEvent(String message){
this.message=message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
发送事件
/**
* Created by 朱大大
* QQ:941556675
*/
EventBus.getDefault().post(messageEvent);
发送粘性事件
/**
* Created by 朱大大
* QQ:941556675
*/
EventBus.getDefault().postSticky(messageEvent);
实战代码
以上我们讲了EventBus的基本用法,接下来我举个栗子,通常我们会有这样一种情况,第一个Activity跳转到第二个Activity,并且把第一个Activity里面的数据传到第二个Activity。还有一种情况是反过来,第二个Activity,结束了finish了,把数据回调给了第一个Activity,这两种情况是我们做项目最常见的。
/**
* Created by 朱大大
* QQ:941556675
*/
public class MessageEvent {
private String message;
public MessageEvent(String message){
this.message=message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
/**
* Created by 朱大大
* QQ:941556675
*/
public class FirstActivity extends AppCompatActivity {
private Button send;
private TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
EventBus.getDefault().register(this);
send=(Button) findViewById(R.id.send);
tv=(TextView) findViewById(R.id.tv);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new MessageEvent("发送到第二个Activity"));
startActivity(new Intent(FirstActivity.this,ScondActivity.class));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void eventBusReceive(MessageEvent event) {
tv.setText(event.getMessage());
}
}
/**
* Created by 朱大大
* QQ:941556675
*/
public class ScondActivity extends AppCompatActivity {
private Button send;
private TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
EventBus.getDefault().register(this);
send=(Button) findViewById(R.id.send);
tv=(TextView) findViewById(R.id.tv);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent("发送到第一个Activity"));
finish();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void eventBusReceive(MessageEvent event) {
tv.setText(event.getMessage());
}
}