新浪微博: AndroidCL 欢迎关注。
新建了一个qq群 482543750,欢迎一起学习Android的小伙伴加入。
提供各种Android学习资料,面试资料,Android简历模板。
一、概述
EventBus是一款Android下的发布/订阅事件总线机制。可以代替Intent、Handler、Broadcast等在Fragment、Activity之间传递消息。
优点:开销小,代码优雅。将发送者和接受者解耦。
二、基本使用
1、导入类库
2、创建一个类,用来保存我们需要传递的消息
public class EventBean {
private String msg;
public EventBean(String msg){
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
3、在要接收消息的页面进行注册
EventBus.getDefault().register(this);
4、另一个页面发送消息
EventBus.getDefault().post(new EventBean("MainActivity接收消息"));
5、接收消息
public void onEventMainThread(EventBean event)
6、解除注册
EventBus.getDefault().unregister(this);
四、实例说明
我们期待实现这样的效果
这是MainActivity
点击按钮进入页面二
布局就不做赘述了
新建类:
package com.lian.eventbusdemo;
/**
* Created by lian on 2016/5/17.
*/
public class EventBean {
private String msg;
public EventBean(String msg){
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
MainActivity代码
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
public class MainActivity extends Activity {
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.btn_main);
textView = (TextView) findViewById(R.id.tv_receive);
//注册EventBus
EventBus.getDefault().register(this);
//点击按钮跳转到页面二
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
//接收消息
// @Subscribe
// public void onMessageEvent(EventBean event){
// Toast.makeText(MainActivity.this, event.getMsg(), Toast.LENGTH_SHORT).show();
// textView.setText(event.getMsg());
// }
//接收消息
@Subscribe
public void onEventMainThread(EventBean event) {
String msg = "onEventMainThread收到了消息:" + event.getMsg();
Log.d("EventBus", msg);
textView.setText(msg);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
//解除注册
EventBus.getDefault().unregister(this);
}
}
MainActivity中的注意事项:
1、所有的事件监听方法都需要用public修饰,包括父类,oncreate(),否则报错:
Caused by: org.greenrobot.eventbus.EventBusException: Subscriber class com.koosol.flowwaternote.MainActivity
2、
事件监听方法上加上
@Subscribe注解,这里跟老版本的EventBus有所不同,老版本的你需要在注解后面配上你所监听的事件的名字,3.0后,直接写上注解就搞定了,而且监听方法的名字也可以随便起了,没有特殊要求。
也就是说,这样写也是对的
//接收消息
@Subscribe
public void suibianxiede(EventBean event) {
String msg = "onEventMainThread收到了消息:" + event.getMsg();
Log.d("EventBus", msg);
textView.setText(msg);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
SecondActivity代码
public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Button button = (Button) findViewById(R.id.btn_send);
//点击按钮向MainActivity传递消息
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new EventBean("MainActivity接收消息"));
}
});
}
}
注意:
事件被post后哪个事件的监听者会响应的问题,这个取决于你写的监听方法所跟的参数类型。
实现了如上效果。
五、其他
(1)关于ThreadMode
假如我们需要在不同的线程中接收消息,可以在注解中设置ThreadMode。
POSTING
:默认的 ThreadMode,表示在执行 Post 操作的线程直接调用订阅者的事件响应方法,不论该线程是否为主线程(UI 线程)。
MAIN
: 在主线程中执行响应方法。
BACKGROUND
: 在后台线程中执行响应方法。
ASYNC
: 不论发布线程是否为主线程,都使用一个空闲线程来处理。
如下所示
//接收消息
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessageEvent(EventBean event) {
String msg = "onEventMainThread收到了消息:" + event.getMsg();
Log.d("EventBus", msg);
textView.setText(msg);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
(2)关于Sticky的使用
发送消息的另一个方法:
EventBus.getDefault().postSticky(new EventBean("MainActivity接收消息"));
什么时候使用呢?
当你并不希望消息被马上处理的时候。
我们通过注解设置消息处理的优先级
//接收消息
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true,priority = 1)
public void onMessageEvent(EventBean event) {
String msg = "onEventMainThread收到了消息:" + event.getMsg();
Log.d("EventBus", msg);
textView.setText(msg);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
priority的值越小,优先级越低
最后,EventBus只能用于线程间通信,不能用于进程间通信