三,EventBus3.0的线程模式

线程模式

EventBus支持订阅者方法在不同于发布事件所在线程的线程中被调用。你可以使用线程模式来指定调用订阅者方法的线程。EventBus总共支持5种线程模式:

  • ThreadMode.POSTING
    • 订阅者方法将在发布事件所在的线程中被调用。也就是发送消息在那个线程,接收消息就在那个线程,比如发送消息在主线程中,接收消息则也在主线中执行,发送消息在子线程中,接收消息则也在相同的子线程中执行
    • 这是 默认的线程模式。
    • 事件的传递是同步的,一旦发布事件,所有该模式的订阅者方法都将被调用。
    • 这种线程模式意味着最少的性能开销,因为它避免了线程的切换。因此,对于不要求是主线程并且耗时很短的简单任务推荐使用该模式。
    • 使用该模式的订阅者方法应该快速返回,以避免阻塞发布事件的线程,这可能是主线程。
  • ThreadMode.MAIN
    • 订阅者方法将在主线程(UI线程)中被调用。
    • 可以在该模式的订阅者方法中直接更新UI界面。
    • 如果发布事件的线程是主线程,那么该模式的订阅者方法将被直接调用。
    • 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程。
  • ThreadMode.MAIN_ORDERED
    • 订阅者方法将在主线程(UI线程)中被调用。
    • 可以在该模式的订阅者方法中直接更新UI界面。
    • 事件将先进入队列然后才发送给订阅者,所以发布事件的调用将立即返回
    • 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程。
    • 不同的线程发送消息,先加入队列的会优先执行
  • ThreadMode.BACKGROUND
    • 订阅者方法将在后台线程中被调用。
    • 如果发布事件的线程不是主线程,那么订阅者方法将直接在该线程中被调用。
    • 如果发布事件的线程是主线程,那么将使用一个单独的后台线程,该线程将按顺序发送所有的事件。
    • 使用该模式的订阅者方法应该快速返回,以避免阻塞后台线程。
  • ThreadMode.ASYNC
    • 订阅者方法将在一个子线程中被调用。
    • 发布事件的调用将立即返回。
    • 该模式适合订阅者方法执行耗时操作,例如网络访问
    • 避免触发大量的长时间运行的订阅者方法,以限制并发线程的数量。
    • EventBus使用了一个线程池来有效地重用已经完成调用订阅者方法的线程。

不同线程模式的使用

ThreadMode.POSTING

A:ThreadMode: POSTING-->主线程中发送

//ThreadMode: POSTING-->主线程中发送
String postting_main_msg 
= "MessageEvent is from ThreadMode POSTING:on mainThread";
post(new PostingMessageEvent(postting_main_msg));

B:ThreadMode: POSTING-->子线程中发送

 //ThreadMode: POSTING-->子线程中发送
 new Thread(new Runnable() {
     @Override
     public void run() {
         String postting_thread_msg = "MessageEvent is from ThreadMode POSTING:on asynchronous";
         post(new PostingMessageEvent(postting_thread_msg));
     }
 }).start();

订阅者接收消息

    //发送消息在什么线程,接收消息就在什么线程
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventThreadModePosting(MessageEvent event) {
        final String str = logMessage(event);
        if (UIUtils.isMainThread()) {
            tvMode.setText(str);
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvMode.setText(str);
                }
            });
        }
    }
ThreadMode.MAIN

ThreadMode: MAIN-->子线程中发送

 //ThreadMode: MAIN-->子线程中发送
new Thread(new Runnable() {
  @Override
     public void run() {
            String postting_thread_msg 
= "MessageEvent is from ThreadMode MAIN:on asynchronous";
         post(newMainMessageEvent(postting_thread_msg));
      }
}).start();

订阅者接收消息

    //无论发送消息在什么线程,接收消息都在主线程
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventThreadModeMain(MainMessageEvent event) {
        final String str = logMessage(event);
        if (UIUtils.isMainThread()) {
            tvMode.setText(str);
        }
    }
ThreadMode.ASYNC

ThreadMode: Async-->主线程中发送

//ThreadMode: Async-->主线程中发送
String async_main_msg 
= "MessageEvent is from ThreadMode Async:on MAIN";
post(new AsyncMessageEvent(async_main_msg));

ThreadMode: Async-->子线程中发送

                //ThreadMode: Async-->子线程中发送
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String postting_thread_msg = "MessageEvent is from ThreadMode Async:on asynchronous";
                        post(new AsyncMessageEvent(postting_thread_msg));
                    }
                }).start();

订阅者接收消息

    //无论发送消息在什么线程,接收消息都在新开辟的子线程中执行
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventThreadModeASYNC(AsyncMessageEvent event) {
        final String str = logMessage(event);
        if (UIUtils.isMainThread()) {
            tvMode.setText(str);
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvMode.setText(str);
                }
            });
        }
    }
ThreadMode.BACKGROUND

ThreadMode.BACKGROUND-->主线程中发送

//ThreadMode.BACKGROUND-->主线程中发送
                String background_main_msg = "MessageEvent is from ThreadMode background:on MAIN";
                post(new BackgroundMessageEvent(background_main_msg));

ThreadMode.BACKGROUND-->子线程中发送

//ThreadMode.BACKGROUND-->子线程中发送
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String btn_background_thread_msg = "MessageEvent is from ThreadMode background:on asynchronous";
                        post(new BackgroundMessageEvent(btn_background_thread_msg));
                    }
                }).start();

订阅者接收消息

    //如果发送消息在主线程,接收消息都在新开辟的子线程中执行,
    //如果发送消息在子线程,接收消息和发送消息在相同的线程.
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventThreadModeBackground(BackgroundMessageEvent event) {
        final String str = logMessage(event);
        if (UIUtils.isMainThread()) {
            tvMode.setText(str);
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvMode.setText(str);
                }
            });
        }
    }
ThreadMode.MAIN_ORDERED

ThreadMode: MAIN_ORDERED-->单线程中发送

                //ThreadMode: MAIN_ORDERED-->单线程中发送
                String btn_background_thread_msg = "MessageEvent is from ThreadMode MAIN_ORDERED:on MAIN";
                post(new OrderedMessageEvent(btn_background_thread_msg));

                String btn_background_thread_msg1 = "MessageEvent1 is from ThreadMode MAIN_ORDERED:on MAIN";
                post(new OrderedMessageEvent(btn_background_thread_msg1));

                String btn_background_thread_msg2 = "MessageEvent2 is from ThreadMode MAIN_ORDERED:on MAIN";
                post(new OrderedMessageEvent(btn_background_thread_msg2));

ThreadMode: MAIN_ORDERED-->多线程中发送

                //ThreadMode: MAIN_ORDERED-->多线程中发送
                for (int i = 0; i < 6; i++) {
                    final String msg = "MessageEvent is from ThreadMode MAIN_ORDERED:on more thread-->" + i;
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            post(new OrderedMessageEvent(msg));
                        }
                    }).start();
                

订阅者接收消息

    //先发消息先处理,处理在主线程执行.
    //如果发送消息在不同的异步线程,那么先加入队列先处理.
    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    public void onEventThreadModeMAIN_ORDERED(OrderedMessageEvent event) {
        final String str = logMessage(event);
        if (UIUtils.isMainThread()) {
            tvMode.setText(str);
        }
    }
demo地址

demo源码

你可能感兴趣的:(三,EventBus3.0的线程模式)