当前位置:   article > 正文

EventBus使用方法_eventbus用法

eventbus用法

EventBus是一个Android端优化的发布/订阅事件总线,以观察者模式实现,简化了应用程序内各组件间、组件与后台线程间的通信 可以轻易切换线程、开辟线程。主要功能是替代Intent, Handler和BroadCastReceiver在Fragment, Activity, Service和线程之间传递消息。优点是开销小,代码更优雅,将发送者和接收者解耦。

环境配置(设置依赖项)

1、使用gradle

compile 'org.greenrobot:eventbus:3.0.0'

2、使用Maven仓库

  1. <dependency>
  2. <groupId>org.greenrobot</groupId>
  3. <artifactId>eventbus</artifactId>
  4. <version>3.0.0</version>
  5. </dependency>

定义事件

  1. public class MessageEvent {
  2. public final String message;
  3. public MessageEvent(String message) {
  4. this.message = message;
  5. }
  6. }

准备订阅者

订阅者实现事件处理方法(也称为“订阅方法”),在事件发布时将被调用。 这些被定义为@Subscribe注解。

  1. // This method will be called when a MessageEvent is posted (in the UI thread for Toast)
  2. @Subscribe(threadMode = ThreadMode.MAIN)
  3. public void onMessageEvent(MessageEvent event) {
  4. Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
  5. }
  6. // This method will be called when a SomeOtherEvent is posted
  7. @Subscribe
  8. public void handleSomethingElse(SomeOtherEvent event) {
  9. doSomethingWith(event);
  10. }


订阅者需要在总线上注册事件和取消注册事件,只有订阅者被注册了,才会接收事件。在Android中使用时,我们需要依据Activity和Fragment的生命周期来注册和解除注册事件,大部分情况下两个操作是放在onStart/onStop生命周期方法里,有时也可能是在onStart/onDestroy里。

  1. @Override
  2. public void onStart() {
  3. super.onStart();
  4. EventBus.getDefault().register(this);
  5. }
  6. @Override
  7. public void onStop() {
  8. EventBus.getDefault().unregister(this);
  9. super.onStop();
  10. }


发布事件

我们可以从代码的任何部分发布事件,与事件类型匹配的所有当前注册的订阅者都将收到该事件。

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));


使用进阶

1、ThreadMode(线程模式)

我们可以使用 ThreadMode 实现线程间的切换,包括后台线程、UI线程、异步线程。
ThreadMode.POSTING
  1. //默认调用方式,在调用post方法的线程执行,避免了线程切换,性能开销最少
  2. // Called in the same thread (default)
  3. @Subscribe(threadMode = ThreadMode.POSTING) // ThreadMode is optional here
  4. public void onMessage(MessageEvent event) {
  5. log(event.message);
  6. }

ThreadMode.MAIN
  1. // Called in Android UI's main thread
  2. @Subscribe(threadMode = ThreadMode.MAIN)
  3. public void onMessage(MessageEvent event) {
  4. textField.setText(event.message);
  5. }
ThreadMode.BACKGROUND
  1. // 如果调用post方法的线程不是主线程,则直接在该线程执行
  2. // 如果是主线程,则切换到后台单例线程,多个方法公用同个后台线程,按顺序执行,避免耗时操作
  3. // Called in the background thread
  4. @Subscribe(threadMode = ThreadMode.BACKGROUND)
  5. public void onMessage(MessageEvent event){
  6. saveToDisk(event.message);
  7. }
 

ThreadMode.ASYNC

  1. //开辟新独立线程,用来执行耗时操作,例如网络访问
  2. //EventBus内部使用了线程池,但是要尽量避免大量长时间运行的异步线程,限制并发线程数量
  3. //可以通过EventBusBuilder修改,默认使用Executors.newCachedThreadPool()
  4. // Called in a separate thread
  5. @Subscribe(threadMode = ThreadMode.ASYNC)
  6. public void onMessage(MessageEvent event){
  7. backend.send(event.message);
  8. }
2、配置EventBusBuilder
EventBus提供了很多配置,一般的情况下我们可以不用配置.但是,如果你有一些其他要求,比如控制日志在开发的时候输出,发布的时候不输出,在开发的时候错误崩溃,而发布的时候不崩溃...等情况。EventBus提供了一个默认的实现,但不是单例。
  1. EventBus eventBus = new EventBus();
  2. //下面这一条的效果是完全一样的
  3. EventBus eventBus = EventBus.builder().build();
  4. //修改默认实现的配置,记住,必须在第一次EventBus.getDefault()之前配置,且只能设置一次。建议在application.onCreate()调用
  5. EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();
3、StickyEvent

StickyEvent在内存中保存最新的消息,取消原有消息,执行最新消息,只有在注册后才会执行,如果没有注册,消息会一直保留来内存中。
  1. //在注册之前发送消息
  2. EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
  1. //限制,新界面启动了
  2. @Override
  3. public void onStart() {
  4. super.onStart();
  5. EventBus.getDefault().register(this);
  6. }
  7. //在onStart调用register后,执行消息
  8. @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
  9. public void onEvent(MessageEvent event) {
  10. // UI updates must run on MainThread
  11. textField.setText(event.message);
  12. }
  13. @Override
  14. public void onStop() {
  15. EventBus.getDefault().unregister(this);
  16. super.onStop();
  17. }

你也可以手动管理StickyEvent
 
  1. MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
  2. // Better check that an event was actually posted before
  3. if(stickyEvent != null) {
  4. // "Consume" the sticky event
  5. EventBus.getDefault().removeStickyEvent(stickyEvent);
  6. //or
  7. EventBus.getDefault().removeAllStickyEvents();
  8. // Now do something with it
  9. }

因为post方法没有过滤StickyEvent,而postSticky是调用post方法的,所以,无论post还是postSticky,StickyEvent是true或false,都会执行。
4、priority事件优先级
  1. //priority越大,级别越高
  2. @Subscribe(priority = 1);
  3. public void onEvent(MessageEvent event) {
  4. }
 
  1. int size = subscriptions.size();
  2. for (int i = 0; i <= size; i++) {
  3. if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
  4. subscriptions.add(i, newSubscription);
  5. break;
  6. }
  7. }

5、中止事件传递
  1. // 中止事件传递,后续事件不在调用,注意,只能在传递事件的时候调用
  2. @Subscribe
  3. public void onEvent(MessageEvent event){
  4. EventBus.getDefault().cancelEventDelivery(event) ;
  5. }

6、index索引加速
EventBus使用了annotation,默认在编译时生成代码,生成索引,添加index后会在编译时运行,自动生成相应代码。
buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
apt {
    arguments {
        eventBusIndex "com.example.myapp.MyEventBusIndex"
    }
}
 
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();

  1. EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
  2. // Now the default instance uses the given index. Use it like this:
  3. EventBus eventBus = EventBus.getDefault();

7、NoSubscriberEvent

如果没找到订阅者事件,可以通过EventBusBuilder设置是否默认发送NoSubscriberEvent,默认是打开的。
 
  1. private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
  2. ....
  3. if (!subscriptionFound) {
  4. if (logNoSubscriberMessages) {
  5. Log.d(TAG, "No subscribers registered for event " + eventClass);
  6. }
  7. if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
  8. eventClass != SubscriberExceptionEvent.class) {
  9. post(new NoSubscriberEvent(this, event));
  10. }
  11. }
  12. }

8、混淆
-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);
}

 

9、建议

将数据封装到一个事件类。所有事件放到一个包下。如果事件太多,同个模块的事件可以考虑使用静态内部类,或者再分包。
 
  1. public class Event {
  2. public static class AListEvent {
  3. public List<A> aList ;
  4. }
  5. public static class BListEvent {
  6. public List<B> bList;
  7. }
  8. }

 
注意:注册和取消注册前要做是否已注册判断,否则会有Subscriber class already registered to event class异常
  1. @Override
  2. protected void onStart() {
  3. super.onStart();
  4. if (!EventBus.getDefault().isRegistered(this)) {
  5. EventBus.getDefault().register(this);
  6. }
  7. }
  8. @Override
  9. public void onStop() {
  10. if (EventBus.getDefault().isRegistered(this)) {
  11. EventBus.getDefault().unregister(this);
  12. }
  13. super.onStop();
  14. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/251136?site
推荐阅读
相关标签
  

闽ICP备14008679号