EventBus是Android开发中经常使用的一个开源库,上手简单,使用方便,适用于在Activity之间,Fragment之间,Activity和Fragment之间传递消息,下面简单介绍一下如何使用EventBus
首先需要引入EventBus开源库到项目中,这里以Android Studio为例,只需要在对应的build.gradle中的dependencies中加上这句即可:
compile 'org.greenrobot:eventbus:3.0.0'
之后项目在build过程中会自动去下载这个库,前提是build的模式不是离线模式。
然后就可以在项目中使用EventBus了,使用的方法分为三步:
1、在需要接收消息的Activity或者Fragment中注册EventBus
这里以Activity为例,在onCreate()方法中注册EventBus:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this); // 在需要接收消息的页面注册EventBus
setContentView(R.layout.first_layout);
}
可以看到注册的方法也很简单,有注册的话就需要有注销,需要在这个Activity被销毁的时候注销掉EventBus:
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this); // 在注册了EventBus页面要被销毁时注销EventBus
}
2、发送消息
使用EventBus发出消息也很简单,不过要先定义一个消息类
public class EventBusMessage {
private String message;
public EventBusMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
消息类也很简单,类名可以是任意的类名,没有要求,然后在消息类中定义一个String类型的成员变量,还有一个获取该成员变量的方法即可。如果消息类型比较复杂的话也可以定义更复杂类型的成员变量,EventBus对这个没有要求。
定义完消息类就可以发送消息了,在需要发送消息的地方写上
EventBus.getDefault().post(new EventBusMessage("这是一个消息"));
即可发送消息
3、接收消息
发送完消息后需要有消息的接收方,消息的接收方需要先注册EventBus之后,定义以下四个方法中至少一个方法之后才可以接收消息:
@Subscribe
public void onEventMainThread(EventBusMessage msg) {
}
@Subscribe
public void onEvent(EventBusMessage msg) {
}
@Subscribe
public void onEventBackground(EventBusMessage msg) {
}
@Subscribe
public void onEventAsync(EventBusMessage msg) {
}
需要注意的是,@Subscribe是不可以省略的,如果省略的话这个方法会收不到消息,变成一个普通的方法,而且如果注册了EventBus之后在这个Activity或者Fragment中没有定义以上四个方法中的任意一个,在运行时会报错:
关于这四个方法的区别以及如何区分由哪个方法来处理消息稍后再解释,先试一下这三步走完之后效果是怎样的,这里先使用onEventMainThread方法,效果图:
关于样式和布局的代码就不贴了,直接贴和EventBus相关的方法
在第一个Activity中点击按钮跳转到第二个Activity后,在第二个Activity的点击按钮函数中写上发送消息的语句,然后销毁这个Activity,发送消息的Activity或者Fragment中是不需要写注册和注销EventBus的语句的
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getDefault().post(new EventBusMessage("我是一个消息"));
finish();
}
});
然后在第一个Activity中定义处理消息的方法,也就是onEventMainThread方法,注意在第一个Activity中要写注册和注销EventBus的语句
@Subscribe
public void onEventMainThread(EventBusMessage msg) {
Toast.makeText(FirstActivity.this, msg.getMessage(), Toast.LENGTH_SHORT).show();
show.setText(msg.getMessage());
Log.i("FirstActivity", "onEventMainThread" + msg.getMessage());
}
接下来介绍一下四个方法的区别
onEventMainThread:不论事件是在哪个线程中发布出来的,在这个方法中定义的处理过程都会在UI线程中执行,使用这个方法可以更新UI,因为Android规定只能在UI线程中更新UI
onEvent:事件从哪个线程发布的,onEvent就会在哪个线程中执行,也就是说发布事件和接收处理事件在同一个线程中执行
onEventBackground:如果事件是在UI线程中发布的,那么onEventBackground中定义的处理过程会在子线程中运行,如果不是在UI线程中发布的,那么处理过程会在发布的线程中执行
onEventAsync:无论事件在哪个线程中发布的,都会创建一个新的线程,处理过程会在这个新线程中进行
那么如果在一个Activity中定义了这四个方法,EventBus如何区分要调用哪一个方法呢
这里要提一下前面提到的消息类,EventBus是用参数类型来区分使用哪一个方法的。需要注意的是EventBus的post方法必须要带一个参数,而且也只能带一个参数。如果四个方法的参数类型相同,而且发送消息的post方法带的参数类型与它们一致,那么这四个方法都会被调用。如果发送消息的post方法带的参数类型与它们都不一致,那么没有任何一个方法会被调用。换句话说,只有参数类型与post方法带的参数类型一致的方法才会被调用,不一致的方法不会被调用。
举个例子,在以下这种接受消息的方法定义的情况下,看一下被调用的方法有哪些
@Subscribe
public void onEventMainThread(EventBusMessage msg) {
Toast.makeText(FirstActivity.this, msg.getMessage(), Toast.LENGTH_SHORT).show();
show.setText(msg.getMessage());
Log.i("FirstActivity", "onEventMainThread" + "被调用了");
}
@Subscribe
public void onEvent(String msg) {
Log.i("FirstActivity", "onEvent" + "被调用了");
}
@Subscribe
public void onEventBackground(EventBusMessage msg) {
Log.i("FirstActivity", "onEventBackground" + "被调用了");
}
@Subscribe
public void onEventAsync(EventBusMessage msg) {
Log.i("FirstActivity", "onEventAsync" + "被调用了");
}
如果发送消息的语句是这样的
EventBus.getDefault().post(new String("我是一个消息"));
那么控制台打印的消息是这样的
换一下发送消息的语句
EventBus.getDefault().post(new EventBusMessage("我是一个消息"));
控制台打印的消息
可以看出,在四个方法中,只有onEvent方法的形参类型是String,其它三个方法的形参类型都是EventBusMessage,因此,当发送消息带的参数类型为String时,onEvent会被调用,而消息的参数类型是EventBusMessage时,其它三个方法会被调用。
有一点要注意的是,在Fragment中使用EventBus时,如果该Fragment还没有被创建,那么在这个Fragment中定义的接收消息的方法是收不到消息的,即使参数类型一致。
关于EventBus的介绍就到这里,这篇博客中所使用的源码已经上传至github,项目地址:https://github.com/sysukehan/AndroidTests.git,为Android Studio项目,其中的EventBusTest模块包含这次使用的代码。
参考文章:
http://blog.csdn.net/harvic880925/article/details/40660137
http://blog.csdn.net/harvic880925/article/details/40787203