EventBus之交付线程(Delivery Threads)

Delivery Threads (ThreadMode)

EventBus可以为您处理线程:事件(events)可以在不同于发布线程(the posting thread)的线程中发布(be posted)。一个常见的用例是处理UI更改。在Android中,UI更改必须在UI(主)线程中完成。另一方面,网络或任何耗时的任务都不能在主线程上运行。EventBus帮助您处理这些任务并与UI线程同步(无需深入研究线程转换、使用AsyncTask等)。

在EventBus中,可以使用四种ThreadMode中的一种来定义调用事件处理方法的线程。

1  ThreadMode: POSTING
2  ThreadMode: MAIN
3  ThreadMode: MAIN_ORDERED
4  ThreadMode: BACKGROUND
5  ThreadMode: ASYNC

ThreadMode: POSTING

将在发布事件的同一线程中调用订阅者,这是默认值。事件交付是同步完成的,一旦发布完成,将调用所有订阅者。这种ThreadMode意味着开销最少,因为它完全避免了线程切换。因此,对于已知不需要主线程就可以在很短的时间内完成的简单任务,推荐使用这种模式。使用此模式的事件处理程序(evemt handler)应快速返回,以避免阻塞可能是主线程的发布线程。示例:

    // Called in the same thread (default)
    // ThreadMode is optional here   
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void refreshMessage(EventData eventData) {
        Log.i(TAG, "method:refreshMessage#" + eventData.getUserName() + ":\n\n" + eventData.getMessage());
    }
2019-08-18 20:30:08.649 6901-6901/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我做了一个好看的小视频
2019-08-18 20:30:08.653 6901-6987/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:30:08.659 6901-6987/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:30:08.660 6901-6987/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我做了一个好看的小视频
2019-08-18 20:30:08.660 6901-6987/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:30:08.660 6901-6987/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我做了一个好看的小视频
2019-08-18 20:45:05.935 7911-7911/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我在FaceBook申请了账号
2019-08-18 20:45:05.940 7911-7949/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-5,5,main]
2019-08-18 20:45:05.944 7911-7949/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[Thread-5,5,main]
2019-08-18 20:45:05.944 7911-7949/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我在FaceBook申请了账号
2019-08-18 20:45:05.944 7911-7949/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[Thread-5,5,main]
2019-08-18 20:45:05.946 7911-7949/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我在FaceBook申请了账号
2019-08-18 20:46:43.636 8068-8068/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我更新了我的相册
2019-08-18 20:46:43.636 8068-8068/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[main,5,main]
2019-08-18 20:46:43.638 8068-8068/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:46:43.638 8068-8068/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我更新了我的相册
2019-08-18 20:46:43.638 8068-8068/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:46:43.638 8068-8068/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我更新了我的相册

ThreadMode: MAIN

订阅者将在Android的主线程中调用(有时称为UI线程)。如果发布线程是主线程,则将直接调用事件处理程序方法(与ThreadMode.POSTING 中描述的同步)。使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。示例:

    // Called in Android UI's main thread    
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void refreshMessage(EventData eventData) {
        Log.i(TAG, "method:refreshMessage#eventData=" + eventData);
        mTvMessage.setText(eventData.getUserName() + ":\n\n" + eventData.getMessage());
    }
2019-08-18 20:49:47.352 8254-8254/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我更新了我的相册
2019-08-18 20:49:47.352 8254-8254/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[main,5,main]
2019-08-18 20:49:47.354 8254-8254/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:49:47.354 8254-8254/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我更新了我的相册
2019-08-18 20:49:47.355 8254-8254/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:49:47.355 8254-8254/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我更新了我的相册
2019-08-18 20:51:01.517 8423-8423/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我做了一个好看的小视频
2019-08-18 20:51:01.522 8423-8464/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:51:01.530 8423-8423/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:51:01.531 8423-8423/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我做了一个好看的小视频
2019-08-18 20:51:01.537 8423-8423/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:51:01.537 8423-8423/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我做了一个好看的小视频

ThreadMode: MAIN_ORDERED

订阅者将在Android的主线程中被调用。事件总是排队(enqueue)等待稍后交付给订阅者,因此对post的调用将立即返回。这使得事件处理的顺序更加严格和一致(因此命名为MAIN_ORDERED)。例如,如果您使用主线程模式在事件处理程序中发布另一个事件,第二个事件处理程序将在第一个事件处理程序之前完成(因为它是同步调用的——将其与方法调用进行比较)。使用MAIN_ORDERED,第一个事件处理程序将完成,然后在稍后的时间点调用第二个事件处理程序(只要主线程具有容量)。

使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。示例:

    // Called in Android UI's main thread
    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    public void refreshMessage(EventData eventData) {
        Log.i(TAG, "method:refreshMessage#eventData=" + eventData);
        mTvMessage.setText(eventData.getUserName() + ":\n\n" + eventData.getMessage());
    }
2019-08-18 20:34:29.971 7152-7152/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我做了一个好看的小视频
2019-08-18 20:34:29.974 7152-7203/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:34:29.984 7152-7152/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:34:29.984 7152-7152/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我做了一个好看的小视频
2019-08-18 20:34:29.985 7152-7152/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[main,5,main]
2019-08-18 20:34:29.985 7152-7152/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我做了一个好看的小视频

ThreadMode: BACKGROUND

订阅者将在后台线程中调用。如果发布线程不是主线程,则将在发布线程中直接调用事件处理程序方法。如果发布线程是主线程,则EventBus使用一个后台线程,该线程将按顺序交付所有事件。使用此模式的事件处理程序应尝试快速返回,以避免阻塞后台线程。

    // Called in the background thread
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void refreshMessage(EventData eventData) {
        Log.i(TAG, "method:refreshMessage#eventData.getUserName() + ":\n\n" + eventData.getMessage());
    }
2019-08-18 20:39:31.024 7532-7532/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我在FaceBook申请了账号
2019-08-18 20:39:31.025 7532-7532/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[main,5,main]
2019-08-18 20:39:31.032 7532-7594/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[pool-1-thread-1,5,main]
2019-08-18 20:39:31.039 7532-7594/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我在FaceBook申请了账号
2019-08-18 20:39:31.040 7532-7594/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[pool-1-thread-1,5,main]
2019-08-18 20:39:31.043 7532-7594/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我在FaceBook申请了账号
2019-08-18 20:37:22.785 7366-7366/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我做了一个好看的小视频
2019-08-18 20:37:22.792 7366-7408/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:37:22.794 7366-7408/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:37:22.794 7366-7408/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我做了一个好看的小视频
2019-08-18 20:37:22.794 7366-7408/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:37:22.794 7366-7408/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我做了一个好看的小视频

ThreadMode: ASYNC

事件处理程序方法在各自单独的线程中调用。这总是独立于发布线程和主线程。发布事件永远不要等待使用此模式的事件处理程序方法。如果事件处理程序方法的执行可能需要一些时间,例如网络访问,则应使用此模式。避免同时触发大量长时间运行的异步处理程序方法来限制并发线程的数量。EventBus使用线程池有效地重用来自已完成的异步事件处理程序通知的线程。

    // Called in a separate thread
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void refreshMessage(EventData eventData) {
        Log.i(TAG, "method:refreshMessage#eventData.getUserName() + ":\n\n" + eventData.getMessage());
    }
2019-08-18 20:42:39.808 7736-7736/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#message=我在FaceBook申请了账号
2019-08-18 20:42:39.818 7736-7775/com.windfallsheng.myeventbus I/PostActivity: method:onCreate#mTvPosting#onClick#currentThread=Thread[Thread-4,5,main]
2019-08-18 20:42:39.829 7736-7776/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#currentThread=Thread[pool-1-thread-1,5,main]
2019-08-18 20:42:39.829 7736-7776/com.windfallsheng.myeventbus I/MainActivity: method:onMessageEvent#message=我在FaceBook申请了账号
2019-08-18 20:42:39.830 7736-7777/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#currentThread=Thread[pool-1-thread-2,5,main]
2019-08-18 20:42:39.830 7736-7777/com.windfallsheng.myeventbus I/PostActivity: method:onMessageEvent#message=我在FaceBook申请了账号

GitHub地址

由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!

Hello , World !

感谢所有!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windfallsheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值