文章参考文章如下:
* http://www.jianshu.com/p/4fa4c7205613
* http://blog.csdn.net/angcyo/article/details/48166849
* http://blog.csdn.net/harvic880925/article/details/40660137
* http://www.tuicool.com/articles/FBbMnay
EventBus的github地址:https://github.com/greenrobot/EventBus
一、什么是EventBus
EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。
二、怎么用
前提:如果是as直接添加依赖
compile 'de.greenrobot:eventbus:3.0.0-beta1'
如果还是eclipse的话,需要下载jar包,可以到这个网站 http://search.maven.org/#search%7Cga%7C1%7Ceventbus上下载,导入lib包即可,我这里下载的是 3.0正式版,点击可以下载
1、注册和注销监听,在activity的2个方法中添加如下
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册监听
EventBus.getDefault().register(this);
}
2、自定义一个消息类,这个就是发布的事件
public class FirstEvent {
private String mMsg;//消息内容
private String tag; //消息类型
public FirstEvent(String mMsg, String tag) {
super();
this.mMsg = mMsg;
this.tag = tag;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public FirstEvent(String msg) {
mMsg = msg;
}
public String getMsg(){
return mMsg;
}
}
@Subscribe(threadMode = ThreadMode.MainThread)
public void helloEventBus(FirstEvent message){
mText.setText(message);
}
ThreadMode.MAIN,事件接收函数执行在UI线程;
ThreadMode.POST,事件在哪个线程发布,接收函数就执行在哪个线程;默认
ThreadMode.ASYNC,事件执行在一个独立的异步线程中。强制在后台执行
ThreadMode.BackgroundThread,如果事件是在UI线程中发布出来的,那么就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么直接在该子线程中执行。
//如果由于事件的发布者是在子线程中,所以BACKGROUND与POSTING模式下订阅者与事件的发布者运行在同一个线程。
//而ASYNC模式下又重新开起一个线程来执行任务。Main模式则是在主线程中运行
priority:默认值为0。订阅了同一个事件的订阅函数,在ThreadMode值相同的前提下,收到事件的优先级,值越大优先级越高。
sticky = true 默认情况下,其为false。什么情况下使用sticky呢?
当你希望你的事件不被马上处理的时候,举个栗子,比如说,在一个详情页点赞之后,产生一个VoteEvent,VoteEvent并不立即被消费,而是等用户退出详情页回到商品列表之后,接收到该事件,然后刷新Adapter等。其实这就是之前我们用startActivityForResult和onActivityResult做的事情。
EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked","1"));
1.事件被post后哪个事件的监听者会响应的问题,这个取决于你写的监听方法所跟的参数类型。如果方法后面的参数是一样的,则所有的方法都会执行。(比如例子里面我post的是一个FirstEvent的对象,则接收方法里所有参数是FirstEvent的函数都会执行)
2.你写的事件监听方法得是public修饰的,如果你写成private了,则不会收到消息。
3.问:当你post了消息之后,你的订阅者有多个,每一个都接收吗?能否做到指定接收者。这个目前有没好的方法?
答:所谓观察者模式,即生产者无需知道其消费者,既然其订阅了该消息,就应该为其发送消息,所以你指的指定接收者,违背了其设计。
但是我又很想指定某个接收者,所以我在对象里多添加了一个tag参数,虽然所有函数都会触发,但我可以指定某些特定条件的代码会执行。一会看例子。
例子
1、我有2个activity,在第2个ac里发送数据,在第1个ac里显示发送的数据
public class MainActivity extends Activity {
Button btn;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eventbus1);
//注册EventBus
EventBus.getDefault().register(this);
btn = (Button) findViewById(R.id.btn_try);
tv = (TextView)findViewById(R.id.tv);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
startActivity(intent);
}
});
}
/**
* 用这个函数来接收消息
* @param event 自己定义的类
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void receiveMsg(FirstEvent event){
String tag=event.getTag();
if(tag!=null&&!TextUtils.isEmpty(tag)){
Log.i("hemiy", "收到了tag的消息");
}else{
String msg = "BACKGROUND收到了消息" + event.getMsg();
tv.setText(msg);
Log.i("hemiy", "不是tag的消息");
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void receiveMsg1(FirstEvent event){
String tag=event.getTag();
if(tag!=null&&!TextUtils.isEmpty(tag)){
Log.i("hemiy", "收到了tag的消息");
}else{
String msg = "BACKGROUND收到了消息" + event.getMsg();
tv.setText(msg);
Log.i("hemiy", "不是tag的消息");
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void receiveMsg2(FirstEvent event){
String tag=event.getTag();
if(tag!=null&&!TextUtils.isEmpty(tag)){
Log.i("hemiy", "收到了tag的消息");
}else{
String msg = "BACKGROUND收到了消息" + event.getMsg();
tv.setText(msg);
Log.i("hemiy", "不是tag的消息");
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void receiveMsg3(FirstEvent event){
String tag=event.getTag();
if(tag!=null&&!TextUtils.isEmpty(tag)){
Log.i("hemiy", "收到了tag的消息");
}else{
String msg = "BACKGROUND收到了消息" + event.getMsg();
tv.setText(msg);
Log.i("hemiy", "不是tag的消息");
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onDestroy(){
super.onDestroy();
//反注册EventBus
EventBus.getDefault().unregister(this);
//或者这么写
/*if(EventBus.getDefault().isRegistered(this)){
EventBus.getDefault().unregister(this);
}*/
}
}
MainActivity的xml布局如下
package eventbus;
import org.greenrobot.eventbus.EventBus;
import com.example.hemiydemo.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class SecondActivity extends Activity {
private Button btn_FirstEvent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eventbus2);
btn_FirstEvent = (Button) findViewById(R.id.btn_first_event);
btn_FirstEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 发送消息是使用EventBus中的Post方法来实现发送的,发送过去的是我们新建的类的实例!
EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked"));
}
});
}
public void sendForOne(View view){
EventBus.getDefault().post(new FirstEvent("指定发送","1"));
}
}
其xml布局如下
1、在secondActivity有2个Button,点击这2个按钮,则MainActivity里面所有的4个接收函数都会触发。因为它们的参数都是FirstEvent。区别就是4个方法执行的线程不同。
2、我在FirstEvent里指定不同的tag,则可以执行特定条件下的代码。也算是指定发送了。