为什么要用EventBus:
EventBus是一个事件总线框架,观察者模式的变形,利用这个框架,我们可以方便高效地在Android组件间传递和处理数据,切换线程,降低代码耦合度。
本文基于 EventBus 3.0。
简单使用
- 配置build.gradle
dependencies {
implementation 'org.greenrobot:eventbus:3.0.0'
}
- 观察者Java代码(以Activity为例)
@Override
protected void onResume() {
super.onResume();
EventBus.getDefault().register(this); //订阅事件
}
@Override
protected void onPause() {
super.onPause();
EventBus.getDefault().unregister(this); //Activity进入后台,取消订阅事件
}
/**
* 事件开始传递时会回调包含 @Subscribe 这个注释的方法
* @param event 传递的数据(Object,为了方便这里直接用String)
*/
@Subscribe
public void onEvent(String event) {
}
- 发送事件
EventBus.getDefault().post("This is an event transfered by EventBus");
发送事件后,所有订阅事件的观察者会回调包含 @Subscribe
这个注释且方法参数为String
的方法,可以把String
换成任何我们需要的Object
来传递数据。
下面说一下EventBus的进阶使用。
线程模式
EventBus总共有四种线程模式:
-
ThreadMode.POSTING
这是缺省模式,onEvent
会在发布事件的线程中运行,即发布事件和接收处理事件将会运行在同一个线程。
这种模式下不要在onEvent
中执行耗时操作,否则会延迟其他观察者的对事件的接收,阻塞线程。 -
ThreadMode.MAIN
不论事件是在哪个线程中发布出来的,onEvent
都会在UI线程中执行,即接收处理事件运行在UI线程中。
当分发事件的线程不在UI线程中时,可以使用这种方法来更新UI。
这种模式下不要在onEvent
中执行耗时操作,否则会延迟其他观察者的对事件的接收,阻塞线程。 -
ThreadMode.BACKGROUND
如果事件从UI线程中分发,那么onEvent
就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEvent
函数直接在该子线程中执行。
这种模式下不要在onEvent
中执行耗时操作,否则会延迟其他观察者的对事件的接收,阻塞线程。 -
ThreadMode.ASYNC
无论事件在哪个线程发布,都会创建新的子线程来执行onEvent
。 -
用例
@Subscribe (threadMode = ThreadMode.ASYNC)
public void onEvent(String event) {
}
粘性事件和事件优先级
这两个概念类似于粘性广播和有序广播,就不具体解释了,看一下用法
- 粘性事件
@Subscribe (sticky = true) //声明可接收粘性事件
public void onEvent(Message m) {
}
EventBus.getDefault().postSticky("Post a sticky event");
这样即便事件先发出去,观察者后订阅的事件,也可以回调onEvent
- 事件优先级
@Subscribe (priority = 2) //声明接收事件的优先级,默认为0,优先级最小
public void onEvent(Message m) {
//类似于有序广播,也可以阻止事件继续分发
EventBus.getDefault().cancelEventDelivery(event) ;
}
事件发送后,会按照优先级的顺序来接收事件。
注解处理器
上文中对EventBus的使用是最基本的使用方法,因为观察者类信息要通过反射获取,所以效率有所欠缺,这里推荐使用Google的注解处理器AnnotationProcessor
,在编译期获取类信息,生成索引,提高运行效率。下面说一下如何配置:
- 配置build.gradle
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ eventBusIndex : 'org.greenrobot.eventbusperf.EventBusIndex' ]
}
}
}
dependencies {
...
implementation 'org.greenrobot:eventbus:3.0.0'
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
- 应用初始化时配置
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus();
}
}
这样配置之后,EventBus的效率就得到了提高,具体使用方法和之前相同。
使用EventBus后的代码混淆
使用EventBus后,代码混淆配置如下:
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
网友评论