EventBus(Kotlin)
参考
suming~
01 简单使用(只需3个文件)
导入依赖
implementation 'org.greenrobot:eventbus:3.2.0'
MessageEvent(类文件)
class MessageEvent(var name : String) {
}
MainActivity(主活动文件)
记得在app的build.gradle中添加build
id 'kotlin-android-extensions'
这样kotlin中可以不使用findViewById得到UI对象,直接使用id作为UI对象
对应的布局中有id为button的按钮和id为textView的文本.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//1 注册事件
EventBus.getDefault().register(this)
//2 点击按钮,跳转到第二个界面(button是id为button的按钮)
button.setOnClickListener{
var intent = Intent(this,MainActivity2::class.java)
startActivity(intent)
}
}
// 5. 注销事件
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this) // 注销事件
}
// 4. 接收到事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(messageEvent: MessageEvent){
//textView是id为textView的文本
textView.setText("${messageEvent.name}")
}
}
MainActivity2(活动文件)
对应的布局中只有id为button的按钮
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
//3. 点击发送事件,并跳转到上一个界面
button.setOnClickListener{
EventBus.getDefault().post(MessageEvent("lee"))
finish()
}
}
}
02 粘性事件的使用(也只需三个文件)
普通事件中,订阅者(接收消息的页面OneActivity)要先注册, 才能接收到发布的事件;也就是说接收消息的页面还没创建或者未注册订阅者,那么处理事件的方法根本无法接收发送者(发送消息页面TwoActivity)发布的事件。
EventBus提供了一种粘性事件,能在发送事件之后再订阅该事件也能接收到该事件。
普通事件是先注册后发布,粘性事件可以先发布后注册。
代码与简单使用不同之处:
- 事件处理方法的注解添加了(sticky = true)
- EventBus.getDefault().postSticky(Object event);来发布事件
- 不需要粘性事件时,需要移除粘性事件.EventBus.getDefault().removeStickyEvent(messageEvent)
MessageEvent(类文件)
与简单使用中的类文件一样
class MessageEvent(var name : String) {
}
因为这里要发送的是粘性事件,先发布事件,所以将MainActivity2作为主活动文件.
MainActivity2(主活动文件)
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
//1. 点击发送粘性事件,并跳转到mainActivity
button.setOnClickListener{
EventBus.getDefault().postSticky(MessageEvent("粘性事件"));
var intent = Intent(this,MainActivity::class.java)
startActivity(intent)
}
}
}
MainActivity(活动文件)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//2 注册事件
EventBus.getDefault().register(this)
//4. 点击按钮,回到第一个界面
button.setOnClickListener{
finish()
}
}
// 3. 接收到事件
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onMessageEvent(messageEvent: MessageEvent){
textView.setText("${messageEvent.name}")
//移除粘性事件
EventBus.getDefault().removeStickyEvent(messageEvent)
}
// 5. 注销事件
override fun onDestroy() {
super.onDestroy()
// 注销事件
EventBus.getDefault().unregister(this)
}
}
03 三要素
EventBus使用的是发布/订阅者模式:
EventBus的三要素
- Event: 事件,可以是任意类型;
- Publisher: 事件发布者,可以在任意线程中发布事件,一般情况,通过EventBus.getDefault()获取EventBus实例,通过post(Object event)发布事件;
- Subscriber:事件订阅者,在EventBus3.0之前,订阅者的事件处理方法必须定义以onEvent开头的具体方法名,而在3.0之后方法名可以可以随意取,但是必须加上@Subscribe()注解,并且指定线程模式,默认为ThreadMode.POSTING。
04 线程
EventBus的几种线程模式
线程模式 | 含义 | 特点 |
---|---|---|
POSTING | 默认线程,表示订阅者将在发布事件的同一线程中被调用 | 适用于不需要主线程就可以在短时间内完成的简单任务,避免了线程切换,开销更小 |
MAIN | 表示在Android中,订阅者在Android主线程中被调用 | 如果发布事件的线程是主线程,订阅者的事件处理函数将直接被调用。如果发布事件的线程不是主线程,则将事件加入主线程队列中,排队等待执行;因此这里不能进行耗时操作,注意不能阻塞主线程 |
MAIN_ORDERED | 表示在Android中,订阅者在Android主线程中被调用 | 与MAIN不同的是,无论发布事件的线程是在哪个线程,事件都将发送到主线程队列总是排队等待传递。注意不能阻塞主线程 |
BACKGROUND | 表示在Android中,订阅者在后台线程中被调用 | 在Android中,如果发布线程不是主线程,订阅者的事件处理函数直接使用该线程,如果发布线程是主线程,那么事件处理函数会开启一个后台线程,有序分发事件,注意不能阻塞后台线程,这里不能进行UI操作;如果不是在Android上,总是使用一个后台线程 |
ASYNC | 表示无论发布线程是什么线程,订阅者都会创建一个新的子线程执行 | 使用于耗时操作,尽量避免同时触发大量的耗时较长的异步操作,EventBus使用线程池高效的复用已经完成异步操作的线程。 |
那么说明POSTING模式的订阅者处理函数线程与发布线程一致,MAIN和MAIN_ORDERED模式的订阅者处理函数线程为主线程,BACKGROUND和ASYNC模式的订阅者处理函数线程为后台线程。
05 优先级
事件优先级, int类型,默认为0;数值越大,优先级越高,在相同线程模式下,优先级高的比优先级低的先接收到事件。
注意:优先级只有在相同线程模式下才有效。
使用:
//在注解处编写.优先级高的先接收事件并处理.
@Subscribe(threadMode = ThreadMode.MAIN, priority = 0)
AndroidEventBus(kotlin)
EventBus的事件处理函数
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onMessageEvent(messageEvent: MessageEvent){
textView.setText("${messageEvent.name}")
//移除粘性事件
EventBus.getDefault().removeStickyEvent(messageEvent)
}
只要函数参数类型和发布的事件的类型相同,就能接收到事件.所以EventBus,不能够订阅特定的事件.
01 AndroidEventBus
订阅者中的订阅函数通过@Subscriber注解来标识tag和线程模型.从而识别事件发布来源
//发布者发布事件,tag为identity
EventBus.getDefault().post(MessageEvent("接收到AndroidBusSendActivity发送的事件"), "identity");
//订阅者的事件处理函数, 有tag为from_three
@Subscriber(tag = "identity", mode = ThreadMode.MAIN)
fun eventAndroidEventBus(message:MessageEvent) {
}
02 简单使用
依赖
implementation 'org.simple:androideventbus:1.0.5.1'
使用方法,除了注解有些不同,其他和EventBus相同.
//订阅者的事件处理函数, 有tag为Tag1
@Subscriber(tag = "Tag1", mode = ThreadMode.MAIN)
fun eventAndroidEventBus(message:MessageEvent) {
}
03 粘性事件使用
不同之处:
- 注册事件,使用 EventBus.getDefault().registerSticky(this)
- 发布粘性事件,EventBus.getDefault().postSticky(MessageEvent(“粘性事件”), “Tag1”);
- 移除粘性事件 EventBus.getDefault().removeStickyEvent(MessageEvent::class.java,“Tag1”)