EventBus 线程调度 threadMode

EventBus 线程调度 threadMode

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
            case POSTING:
                invokeSubscriber(subscription, event);
                break;
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);
                } else {
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
            case MAIN_ORDERED:
                if (mainThreadPoster != null) {
                    mainThreadPoster.enqueue(subscription, event);
                } else {
                    // temporary: technically not correct as poster not decoupled from subscriber
                    invokeSubscriber(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }

一共五个调度方法:

  • POSTING:在当前调用EventBus#post(event)的线程执行
  • MAIN:在主线程(即Android的UI线程)执行
  • MAIN_ORDERED:在主线程(即Android的UI线程)执行。 与 MAIN不同的是,该事件将始终排队等待发布,这确保了事件发布不会被阻塞;
  • BACKGROUND:当前执行线程为主线程,就切换到后台线程执行;当前线程为非主线程,则就在当前线程执行
  • ASYNC:新开后台线程执行

POSTING,则调用

invokeSubscriber(subscription, event);
    void invokeSubscriber(Subscription subscription, Object event) {
        try {
            subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
        } catch (InvocationTargetException e) {
            handleSubscriberException(subscription, event, e.getCause());
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unexpected exception", e);
        }
    }

在当前线程中直接反射调用订阅方法;

MAIN,则调用

if (isMainThread) {
    invokeSubscriber(subscription, event);
} else {
    mainThreadPoster.enqueue(subscription, event);
}

如果当前线程是主线程则直接反射调用,否则则去切换线程(切到主线程),然后调用invokeSubscriber方法;

MAIN_ORDER:

if (mainThreadPoster != null) {
    mainThreadPoster.enqueue(subscription, event);
} else {
    // temporary: technically not correct as poster not decoupled from subscriber
    invokeSubscriber(subscription, event);
}

如果mainThreadPoster不为空则在主线程中执行,否则在当前线程中执行,与MAIN的区别是MAIN判断后线程后立刻执行,儿而MAIN_ORDER则是在创建主线程的Handler中排队发消息执行;

BACKGROUND:

if (isMainThread) {
    backgroundPoster.enqueue(subscription, event);
} else {
    invokeSubscriber(subscription, event);
}

如果当前是主线程,则线程调度到后台线程执行,否则就在当前线程执行;

public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!executorRunning) {
                executorRunning = true;
                eventBus.getExecutorService().execute(this);
            }
        }
    }

拿到一个等待发生事件对象,把事件扔到链表中,用一个运行中executorRunning做标签;调用了

eventBus.getExecutorService().execute(this);
ExecutorService getExecutorService() {
        return executorService;
    }
private final ExecutorService executorService;

executorService = builder.executorService;

ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;

private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

默认搞了一个缓存线程池,无限大;

开辟子线程,在子线程中调用invokeSubscriber;

ASYNC:

asyncPoster.enqueue(subscription, event);

也是在线程池中直接开辟一个子线程,然后调用invokeSubscriber;

线程调度默认是POSTING:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    boolean sticky() default false;

    int priority() default 0;
}

你可能感兴趣的:(源码学习,EventBus)