简介 Eventbus 是适用于Android和Java的发布/订阅事件总线,简化了应用程序内各组件、组件与后台线程之间的通信。
角色
Event
:事件,可以是任意类型,EventBus会根据事件类型进行全局通知。
Subscriber
:事件订阅者,事件处理的方法名随意,不过需要注解@subscribe
和指定线程模式(默认POSTING
)。
Publisher
:事件发布者,可以在任意线程中发布事件,使用EventBus.getDefault()
就可以得到一个EventBus对象,然后再调用post(Object)
方法即可。
线程模式
POSTING
:默认,表示事件处理函数线程与发布事件线程在同一线程中。可以避免线程切换因此速度最快。注意应尽快返回避免阻塞可能在主线程中的发布线程。
MAIN
:表示事件处理函数线程在主线程(UI线程)中。注意应尽快返回避免阻塞主线程。
MAIN_ORDERED
:表示事件处理函数线程在Android主线程中。事件将始终排入队列,拥有更严格和更一致的顺序。注意应尽快返回避免阻塞。
BACKGROUND
:表示事件处理函数线程在后台线程中。如果发布事件线程在主线程(UI线程)中,则事件处理函数将会开启一个后台线程;如果发布事件线程是在后台线程,那么事件处理函数就使用该后台线程。注意应尽快返回避免阻塞主线程。
ASYNC
:表示事件处理函数将会在新建子线程中。如果执行可能需要一些时间,则应使用此模式。
关系图
优点 EventBus
可以是替代Intent
、Handler
、BroadCast
在Activity
、Fragment
、Service
线程之间传递消息。拥有速度快、消耗低、代码优雅、高级功能、将事件发布者与事件订阅者解耦等优点。
教程 导入 在build.gradle(Module)
中添加EventBus
依赖。
build.gradle(Module) 1 2 3 4 dependencies { ... implementation 'org.greenrobot:eventbus:3.2.0' }
定义事件 此事件由Publisher(事件发布者)
发出,到Subscriber(事件订阅者)
接收。
MessageEventBus.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import android.os.Bundle;public class MessageEventBus { private String type; private Bundle data; public MessageEventBus (String type, Bundle data) { this .type = type; this .data = data; } public String getType () { return type; } public void setType (String type) { this .type = type; } public Bundle getData () { return data; } public void setData (Bundle data) { this .data = data; } }
注册与注销事件订阅者 通常根据Activity
、Fragment
、Service
的生命周期进行注册。
MainActivity.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this ); } @Override protected void onDestroy () { super .onDestroy(); EventBus.getDefault().unregister(this ); }
定义事件订阅者 MainActivity.java 1 2 3 4 5 6 7 8 9 @Subscribe(threadMode = ThreadMode.MAIN) public void onEventBus (MessageEventBus message) { Bundle data = message.getData(); switch (message.getType()) { case "simple" : data.getString("value" ) break ; } }
发布事件 MainActivity.java 1 2 3 Bundle data = new Bundle ();data.putString("value" , "test" ); EventBus.getDefault().post(new MessageEventBus ("simple" , data));
粘性事件 EventBus
将某种类型的最后一个粘性事件保留在内存中,然后粘性事件就可以被事件订阅者收到或被查询。
示例 某个粘性事件在一段时间前发布。
MainActivity.java 1 EventBus.getDefault().postSticky(new MessageEventBus ("sticky" , null ));
然后定义一个粘性事件订阅者,它将立即收到之前发布过的粘性事件。
MainActivity.java 1 2 3 4 @Subscribe(sticky = true) public void onEventBus (MessageEventBus message) { ··· }
删除 当不需要使用某个粘性事件时,可以将其删除,并且会返回之前的粘滞事件。
MainActivity.java 1 MessageEventBus event = EventBus.getDefault().removeStickyEvent(MessageEventBus.class);
优先级 可以通过提供优先级以改变事件传递的顺序。在同一ThreadMode(传递线程)
中,优先级较高的订阅者将在优先级较低的订阅者之前收到事件,默认优先级为0。
MainActivity.java 1 2 3 4 @Subscribe(priority = 1) public void onEventBus (MessageEventBus message) { ··· }
取消事件传递 如果不需要事件继续传递,可以取消事件传递,仅限于在POSTING
线程模式中。
MainActivity.java 1 2 3 4 5 @Subscribe(threadMode = ThreadMode.POSTING) public void onEventBus (MessageEventBus message) { ··· EventBus.getDefault().cancelEventDelivery(message); }
混淆规则 如果项目使用了ProGuard
,则需要在proguard-rules.pro
中添加指定规则。
proguard-rules.pro 1 2 3 4 5 6 7 8 9 10 -keepattributes *Annotation* -keepclassmembers class * { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # And if you use AsyncExecutor: -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
参考资料