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());
    }

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());
    }

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());
    }

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());
    }

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());
    }

 

GitHub地址

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

Hello , World !

感谢所有!

上一篇:spreadjs~~一个Excel在线编辑的工具


下一篇:UE4 Persona 骨架网格物体动画