1.EventBus介绍
EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如耗时操作完成后通知更新UI。
官方文档:http://greenrobot.org/eventbus/documentation
github地址:https://github.com/greenrobot/EventBus
Event:传递的事件对象
Subscriber:事件的订阅者
Publisher:事件的发布者
threadMode:用于定义函数在哪个线程中执行
PostThrad:订阅者将会在和发布者同一线程被调用。这是默认行为。同时这也是开销耗费最少的行为,因为它避免了线程之间的转换。所以如果你知道你的任务耗费的时间非常少,同时不一定要在主线程中完成,那么将推荐使用这种模式。订阅者使用这种模式必须尽快返回以避免阻塞可能是主线程的发布者线程。
MainThread:订阅者将在android的主线程中被调用。
BackgroudThread:订阅者将在子线程被调用。如果发布者的线程不是主线程,那么订阅者将直接在发布者的线程被调用。如果发布者的线程是主线程,那么EventBus将使用一条单独的子线程来顺序地处理它的所有事件。
Async:订阅者将会在单独的一条线程中被调用。这条线程总是独立于发布者的线程以及主线程。使用这种模式发布事件不会等待事件处理方法的返回。如果你的事件处理方法需要耗费很长时间,那么订阅者需要使用这种模式
2.基本使用
studio添加依赖库:compile 'org.greenrobot:eventbus:3.0.0'
eclipse导入jar包 EventBus 3.0下载地址
订阅
如果需要在一个Activity中接受事件,即订阅者,需要在该Activity中注册EventBus事件,在onDestroy中注销。
也就是1注册,2写订阅函数,3注销
下面看具体的使用
先贴主界面的代码,主界面也就是三个订阅函数,用于接收订阅消息,订阅函数的方法名可以任意,需要在上面添加注解,指定threadMode,sticky,priority,分别就是指定在哪个线程执行,是否粘性,优先级。方法名的参数类型,就是要接收的类型。
还有两个按钮,分别跳转第二第三个界面,在onDestroy中注销EventBus
public class MainActivity extends AppCompatActivity {
private static final String TAG = "lzy";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
//订阅
@Subscribe(threadMode = ThreadMode.MAIN)
public void helloEventBus(String message) {
Log.i(TAG, "第一个界面收到String: " + message);
}
//订阅
@Subscribe(threadMode = ThreadMode.MAIN)
public void helloEventBus2(Object message) {
Log.i(TAG, "第一个界面String的父类收到:" + message);
}
//订阅
@Subscribe(threadMode = ThreadMode.MAIN)
public void helloEventBus3(EventMessage message) {
Log.i(TAG, "第一个界面收到Object:" + message);
}
public void jump2(View view) {
startActivity(new Intent(this, SecondActivity.class));
}
public void jump3(View view) {
startActivity(new Intent(this, ThirdActivity.class));
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
下面是第二个界面的代码
与第一个界面类似,不同之处是,一个发布粘性事件的按钮,还有一个跳转第三个界面的按钮,注意,这里在onDestroy中并没有去注销EventBus
public class SecondActivity extends AppCompatActivity {
private static final String TAG = "lzy";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
EventBus.getDefault().register(this);
}
//订阅
@Subscribe(threadMode = ThreadMode.MAIN)
public void helloEventBus(String message) {
Log.i(TAG, "第二个界面收到String:" + message);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void helloObjectEventBus(EventMessage message) {
Log.i(TAG, "第二个界面收到Object:" + message.getName());
}
@Override
protected void onDestroy() {
// EventBus.getDefault().unregister(this);
super.onDestroy();
}
public void jump(View v) {
startActivity(new Intent(this, ThirdActivity.class));
}
public void publish2(View v) {
EventBus.getDefault().postSticky("来自第二个界面的Sticky Message");
}
}
下面是第三个界面代码
这个界面是两个发布的按钮,还有个接收的订阅函数,但是指定了他为粘性的
public class ThirdActivity extends AppCompatActivity {
private static final String TAG = "lzy";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
EventBus.getDefault().register(this);
}
public void bt1(View view) {
String string = "来自第三个界面的Message";
EventBus.getDefault().post(string);
}
public void bt2(View view) {
EventBus.getDefault().post(new EventMessage("来自第三个界面的Object Message", "21"));
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void event(String message) {
Log.i(TAG, "第三个界面收到String: " + message);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
下面进行分析
1.点击跳转第二个界面,再点击跳转第三个界面,点击发布String
可以看到三个界面因为注册了订阅者,所以订阅函数为String类型的都收到了,也可以看到参数为Object类型的也收到了,这是因为默认的eventInheritance为true,而eventInheritance控制着发布参数类型的父类是否能接收到,显然Object为所有的父类,自然能接收到。
2.点击跳转第二个界面,再点击跳转第三个界面,点击发布EventMessaget类型,EventMessage为自定义的一个类
要收到消息首先Activity要注册订阅,并且订阅函数的类型为EventMessage类型或者是其父类,所以就如上图打印的一样
3.点击跳转第二个界面,点击发布粘性事件,再点击跳转到第三个界面
发布过前两个界面正常接收到消息,然而再点击进入第三个界面时,立即也收到了上个界面发布的粘性事件,第二个界面在发布的时候,第三个界面还并没,有注册订阅,所以这是为什么?这是因为第三个界面在注册的时候,会从缓存中取出之前发布的粘性事件,再判断这个订阅者的订阅方法是否是粘性的,是就立即进行发布,所以第三个界面才接收到了,这也可以看我另一篇的源码分析
4.点击跳转第二个界面,再返回第一个界面,再点击跳转第三个界面,在点击发布
你会发现第二个界面依然会收到订阅消息,很明显是因为我们在第二个界面销毁时没有注销订阅,所以会接收到
OK完成,不知道写的清不清楚