前言
开发过程中我们总会碰到如下几种情况:
- 需要全局在每个页面对一种事件进行处理,比如用户登出,断网提醒
- 用户从父页面进入子页面,子页面要同时修改自己和父页面的数据,比如购物车
- 组件间通信
虽然说安卓的原生机制提供了部分能力解决上述问题,比如onActivityResult解决购物车信息同步问题,比如广播机制解决用户登录状态问题,但是实现复杂,调用开销大,代码逻辑也不够清晰。EventBus就是一个足够轻量、几乎没有的学习成本的解决方案。
概述
由于eventbus的概念过于简单了,就不上图赘述了,简而言之,以任意POJO作为事件主体,消息内容放在POJO的字段中发送,所有注册监听改事件的函数都会在事件发送时被调用。回调函数可以指定工作线程。事件有两种形式,普通事件和粘性事件,粘性事件可以接受在监听函数注册方法调用前的所有历史事件。
Code
依赖
首先引入依赖
implementation 'org.greenrobot:eventbus:3.2.0'
EventBus的使用方法非常简单,只有两种注册方法,class中定义注册函数,监听类注册为自己,或直接注册匿名类。
事件定义
首先定义一个事件
加入你的事件不需要附加额外的信息,那么这个事件类非常简洁:
class TaskAddedEvent
如果你想要携带一些附加信息的话
data class TaskAddedEvent(
val id: Int,
val name: String
)
监听回调
编写一个只有事件类型作为参数的函数,加上@Subscribe注解就可以了。但这时发送的事件还不能被处理,因为没有注册。
@Subscribe
fun onTaskAddedEvent(event: TaskAddedEvent) {
}
注册函数
如果你的监听回调写在activity或者类中,那么直接在生命周期中注册自身就好。 记得一定要在生命周期结束的时候解除注册,否则会造成内存泄漏。
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
注意,例如你想写一个断网监听功能在收到断网消息后界面弹出提醒,想在每个activity中都能接受到这个消息,所以把这个通用的监听回调写在一个通用的activity中,其余页面继承这个activity,然后通过上述操作注册自己,但是你会发现,不管你在哪里register都是不行滴。EventBus机制如此,因此,使用下面的方式曲线救国。
val networkCallback = object {
@Subscribe
fun onTaskAddedEvent(event: TaskAddedEvent) {
}
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(networkCallback)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(networkCallback)
}
发送事件
EventBus.getDefault().post(TaskAddedEvent(1, "hello world"))
建议把这个发送事件做一层封装,增加一些例如打印消息内容的方法便于调试。
fun postEvent(event: Any) {
Log.d("EventBus", event.toString())
EventBus.getDefault().post(event)
}
以上