一、添加依赖: compile ‘org.greenrobot:eventbus:3.0.0’
二、先看一个小demo
MainActivity
布局文件太过于简单就不贴出来了,就是一个TextView一个Button;
这里实现功能就是Button一个点击跳转到SecendActivity界面;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecendActivity.class);
startActivity(intent);
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onShowMessageEvent(MessageEvent messageEvent){
tv.setText("Message From ActivityB :"+messageEvent.getMessage());
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
SecendActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secend);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent("ni hao FirstActivity"));
SecendActivity.this.finish();
}
});
}
MessageEvent:
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;
}
}
这里的逻辑也是一目了然:SecendActivity中也有且只有一个Button用来点击触发: EventBus.getDefault().post(new MessageEvent(“ni hao FirstActivity”));这行代码的逻辑;
这里简单解释一下就是:这行代码发送了一个MessageEvent对象,因为我们添加了依赖,并且在MainActivity中注册EventBus的,最最关键的是我们声明了方法:onShowMessageEvent()这个方法的参数就是一个MessageEvent,会根据合适的事件参数来匹配相应的方法;
三、注解中的线程模型
在EventBus的事件处理函数中需要指定线程模型,即指定事件处理函数运行所在的想线程。在上面我们已经接触到了EventBus的四种线程模型。那他们有什么区别呢?在EventBus中的观察者通常有四种线程模型,分别是PostThread(默认)、MainThread、BackgroundThread与Async。
首先解释一下什么是发布事件:EventBus.getDefault().post();方法所执行的地方叫做发布事件的地方;
PostThread:如果使用事件处理函数指定了线程模型为PostThread,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为PostThread的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
MainThread:如果使用事件处理函数指定了线程模型为MainThread,那么不论事件是在哪个线程中发布出来的,该事件处理函数都会在UI线程中执行。该方法可以用来更新UI,但是不能处理耗时操作。
BackgroundThread:如果使用事件处理函数指定了线程模型为BackgroundThread,那么如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
Async:如果使用事件处理函数指定了线程模型为Async,那么无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行。同样,此事件处理函数中禁止进行UI更新操作。
四、粘性事件
粘性事件就是A需要通过post发布消息,这个消息需要B处理即注册了EventBus事件的地方,但是在A发送消息的时候B并没有注册该事件的处理,粘性事件的意思就是在这种情况下,B再注册事件之后马上就能收到A之前已经发送过来的消息,但是也有限制:
这个事件是最近发布的那个事件
用法:
订阅粘性事件:
EventBus.getDefault().register(Activity.this);
粘性事件处理方法:
@Subscribe(sticky = true)
public void XXX(MessageEvent messageEvent) {
......
}
发送粘性事件:
EventBus.getDefault().postSticky(new MessageEvent("test"));
例子:
public class StickyModeActivity extends AppCompatActivity {
int index = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sticky_mode);
findViewById(R.id.post).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new MessageEvent("test" + index++));
}
});
findViewById(R.id.regist).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().registerSticky(StickyModeActivity.this);
}
});
findViewById(R.id.unregist).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().unregister(StickyModeActivity.this);
}
});
}
@Subscribe(threadMode = ThreadMode.MainThread, sticky = true)
public void onMessageEventMainThread(MessageEvent messageEvent) {
Log.e("MainThread", messageEvent.getMessage());
}
}
以上代码中有三个按钮 控制按钮的点击事件的顺序就可以得到想要的效果;
小结
简单学习了一下EventBus的使用方法,感觉接口回调,广播接收器,各有各的使用场景吧,不过使用起来还是很方便快捷的,而且使用的地方也很广泛,最大的好处还是不用我们考虑主线程和子线程中UI、网络访问等等复杂的问题,一个注解就能解决;
注册EventBus的Activity就像是一个订阅者订阅了某个事件——事件作为参数由处理事件方法处理该事件(像是观察者),事件发生的地方会很多——post事件的地方(就像是被观察者);
希望能慢慢摸索EventBus更多的原理性的东西,更更加复杂确不失灵活的使用的方法!
参考博客地址:https://segmentfault.com/a/1190000004276926
最后感谢各种无私奉献的人!