作为一个
Android
开发者,我们在日常的开发中肯定会使用到EventBus
,比如说当我们在做app
的消息模块的时候,接收到后台推送的消息之后,为了方便用户查看,就需要把消息保存到本地,正常情况下在页面上会有个badge
显示消息数量,如果我们不在badge
显示界面的话,就需要在接收到后台推送之后更新badge
上显示的消息数量,这个时候就可以使用EventBus
发出一个事件,这样订阅者接收到事件之后,就会从数据库拿未读消息数,显示在badge
上面。说了这么多,下面就简单的介绍下EventBus
的使用:
EventBus
地址:GitHub
一、EventBus 介绍
ventBus
是一个Android
端优化的publish/subscribe
消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。这个消息总线主要有三个部分:
- 事件(Event)
- 事件订阅者(Subscriber)(有没有想到
RxJava
里面的订阅者 ==。) - 事件发布者(Publisher)
特征叙述:
- 简化组件间的通信
- 事件发送者和接收者解耦
- 在活动、片段和后台线程中执行良好
- 避免了复杂、易出错的依赖关系和生命周期问题
- 使你的代码更加简单
- 快!
- 小!(大约50K)
- 在100,000,000+个程序上使用
- 先进特征,比如指定线程、设置优先级等
二、使用EventBus仅需四步
1. 添加依赖
使用Gradle
:
compile 'org.greenrobot:eventbus:3.0.0'
或者Maven
:
<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.0.0</version>
</dependency>
又或者下载Jar
包添加到项目中
jar包下载
2. 定义事件(Event)
public class TestMsg {
}
这个TestMsg
由从事件发布者发出,到事件订阅者接收,当然也可以加上额外的信息,比如下面可以传递name
:
public class TestMsg {
private String name;
public TestMsg(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
3. 定义事件接收者(Subscriber)
首先在所属的Activity
的onCreate()
里面注册
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_lib);
EventBus.getDefault().register(this);
}
在onDestory
里面取消注册
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
然后定义处理事件:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(TestMsg testMsg) {
if (testMsg != null) {
Log.d("MainActivity", "你收到的名字为: "+testMsg.getName());
}
}
这里的定义了事件接收者以及使用注解@Subscribe(threadMode = ThreadMode.MAIN)
指定了执行的线程。ThreadMode
有下面四种类型:
MAIN UI
主线程POSTING
默认调用方式,在调用post方法的线程执行,避免了线程切换,性能开销最少BACKGROUND
如果调用post
方法的线程不是主线程,则直接在该线程执行。
如果是主线程,则切换到后台单例线程,多个方法公用同个后台线程,按顺序执行,避免耗时操作ASYNC
开辟新独立线程,用来执行耗时操作,例如网络访问。
当然这里可以在注解里面设置优先级,比如下面设置优先级为100,越大就越线先接收到事件:
@Subscribe(threadMode = ThreadMode.POSTING,priority = 100)
public void onEventMainThread(TestMsg testMsg) {
if (testMsg != null) {
Log.d("MainActivity", "你收到的名字为: "+testMsg.getName());
}
}
如果你有三个接收事件,并且设置了不同的优先级,比如100、50、10,你也可以在priority = 100
的接收到之后取消事件的传递,那么priority
= 50和10的就不会接收到事件了。但是请注意,只能在ThreadMode.PostThread
类型的才能取消,其他的三种ThreadMode
类型是不能取消的。
如何设置:
EventBus.getDefault().cancelEventDelivery(event) ;
4.定义事件发布者(Publisher)发出事件
sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new TestMsg("测试EventBus"));
}
});
我写了一个小Demo
,这个Demo
是我在主module
,也就是在app
下面定义了事件接收者,在主app
依赖的module
下面发出事件来测试的。结果是可行的。有兴趣的小伙伴可以去看下: