EventBus使用

作者: 会飞的大象 | 来源:发表于2015-08-05 14:23 被阅读5430次

    本文主要翻译自:
    https://github.com/greenrobot/EventBus/blob/master/HOWTO.md

    1. 功能介绍

    1.1. EventBus

    EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递。

    1.2 主要对象

    事件 (Event)
    发布者 (Publisher)
    订阅者 (Subscriber)


    2. 流程图

    流程图

    3. 类图

    类图

    4. 使用方法

    4.1 使用EventBus三步

    定义事件:

    public class MessageEvent {
        public final String message;
    
        public MessageEvent(String message) {
            this.message = message;
        }
    }
    

    订阅者注册事件

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    
    @Override
    public void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }
    
    // This method will be called when a MessageEvent is posted
    public void onEvent(MessageEvent event){
        Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
    }
    
    // This method will be called when a SomeOtherEvent is posted
    public void onEvent(SomeOtherEvent event){
        doSomethingWith(event);
    }
    

    发布事件

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

    4.2 交付线程和ThreadModes

    事件可以在不同的线程之间传递
    ThreadMode:

    • PostThread
      这是默认的模式,订阅者会在发布者所在的线程中调用。这种模式开销最小,避免了线程之间的切换。所以完成时间很短,并且不需要主线程参与的简单任务建议使用这种模式。例如:
    // Called in the same thread (default)
    public void onEvent(MessageEvent event) {
        log(event.message);
    } 
    
    • MainThread
      这种模式订阅者会在主线程中调用。如果事件发布是在主线程,那么事件处理程序会立即被调用。使用这种模式事件处理必须尽快返回,以避免阻塞主线程。例如:
    // Called in Android UI's main thread
    public void onEventMainThread(MessageEvent event) {
        textField.setText(event.message);
    }
    
    • BackgroundThread
      这种模式订阅者会在后台线程中调用。如果事件发布不在主线程,事件处理方法会直接在发布线程中调用;如果事件发布在主线程,EventBus则会依次传递所有的事件到一个后台进程。使用这种模式必须尽快返回以避免阻塞后台进程。
    // Called in the background thread
    public void onEventBackgroundThread(MessageEvent event){
        saveToDisk(event.message);
    }
    
    • Async
      事件处理方法在一个单独的线程中调用。他始终是独立于发布线程和主线程。发布事件不需要等待事件处理方法的完成。如果使用耗时的操作应当使用这种模式,比如连接网络。应当避免同一时间触发大量的、长时间运行的异步处理方法,从而限制并发线程的数量。EventBus使用了线程池来有效的重用线程。
    // Called in a separate thread
    public void onEventAsync(MessageEvent event){
        backend.send(event.message);
    }
    

    4.3 订阅者优先级以及事件传递顺序

    我们可以通过定义优先级来决定事件的传递顺序

    int priority = 1;
    EventBus.getDefault().register(this, priority); 
    

    在同一个ThreadMode中,优先级高的订阅者会先接收到事件。默认的优先级是0。优先级在不同的ThreadModes中是没有效果的


    4.4 使用EventBusBuilder配置EventBus

    EventBus2.3增加了EventBusBuilder来配置EventBus。例如:配置一个当事件没有订阅者的时候,发布一个事件时,EventBus不做任何事情。

    EventBus eventBus = EventBus.builder()
    .logNoSubscriberMessages(false)
    .sendNoSubscriberEvent(false).build();
    

    更多设置请查看 EventBusBuilder 类和他的javaDoc

    4.5 配置默认的EventBus实例

    最简单的方式是使用EventBus.getDefault()来获取一个共享的EventBus实例,同时可以使用EventBusBuilder的installDefaultEventBus()来创建默认实例。
    例如:可能需要配置一个默认的EventBus实例来将在onEvent()方法中的例外再次抛出,但是我们只想在debug模式中这样做,因为这位导致app的崩溃。

    EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();
    

    在EventBus实例第一次使用前,这种配置只能做一次,从而确保在应用程序中的一致性。最好的地方是在Application类中进行初始化。

    4.6 取消事件发送

    当取消事件发送后,后面的订阅者就不再会接收到事件

    // Called in the same thread (default)
    public void onEvent(MessageEvent event){
        // Process the event 
        ...
    
        EventBus.getDefault().cancelEventDelivery(event) ;
    }
    

    事件通常是在较高优先级的订阅者中取消。取消动作仅限于运行在发布线程的事件处理方法。

    4.7 sticky事件

    一些事件携带的信息只有在其发布之后才会被关注。例如,有些事件会标记一些初始化的完成。或者一些传感器或者位置数据需要获取最新的值,这些情况我们就可以使用sticky事件。EventBus会在内存中保留某种类型最新的sticky事件

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

    在stickyEvent发布后,当有新的Activity启动,并注册了sticky事件,他就会立刻收到该事件

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().registerSticky(this);
    }
    
    public void onEventMainThread(MessageEvent event) {
        textField.setText(event.message);
    }
    
    @Override
    public void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }
    

    我们也可以来获取指定类型的sticky事件

    EventBus.getDefault().getStickyEvent(Class<?> eventType)
    

    4.8 混淆的配置

    -keepclassmembers class ** {
        public void onEvent*(**);
    }
    
    # Only required if you use AsyncExecutor
    -keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent {
        <init>(java.lang.Throwable);
    }
    

    5. 加入EventBus到项目中

    Gradle:

    compile 'de.greenrobot:eventbus:2.4.0'
    

    Maven:

    <dependency>
    <groupId>de.greenrobot</groupId>
    <artifactId>eventbus</artifactId>
    <version>2.4.0</version>
    </dependency>

    相关文章

      网友评论

      • KIMDA:发布者和订阅者的单词写错了~~所以~~流程图也写错了楼主:flushed:
        会飞的大象:@A_U_X 感谢指正,已更新
        f85fff9c9fc3:我也看到了,怪不得一脸慒毕,看着图

      本文标题:EventBus使用

      本文链接:https://www.haomeiwen.com/subject/tngvqttx.html