首页 > 代码库 > 由浅入深了解EventBus:(六)

由浅入深了解EventBus:(六)

线程模型

  在EventBus3.0框架中执行线程的快速切换,通过ThreadMode来指定线程在哪个线程中执行;

  在EventBus3.0框架线程模型有个PendingPost 类负责数据的传递;

final class PendingPost {    private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();    Object event;    Subscription subscription;    PendingPost next;    private PendingPost(Object event, Subscription subscription) {        this.event = event;        this.subscription = subscription;    }}

     PendingPost 类中维护了3个字段,其中event为事件类的实例,subscription是监听回调信息封装,next 的类型也是一个PendingPost ,通过next可以构建一个列表;

在类的内部也维护着一个静态的PendingPost 对象的对象池,当需要PendingPost 实例时,首先从对象池中获取,当获取不到时在进行对象的new创建;

    ThreadMode.MAIN 当调用线程不是主线程时,需要把事件执行推送到主线程中,在EventBus3.0框架中的EventBus类中维护着一个HandlerPoster对象来进行主线程数据的处理;HandlerPoster类是一个Handler,监听事件函数的执行应该在主线程回调的handleMessage 方法中,在源码中也确实是在handleMessage方法执行:

    eventBus.invokeSubscriber(pendingPost);

ThreadMode.
Background 与ThreadMode.AsyncPoster 执行的方式差不多相同,都是从后台线程池中取出线程进行执行;在EventBus类中初始化了BackgroundPoster与AsyncPoster来对这2种线程模型进行处理,这2个类都继承了Runnable 接口;
final class BackgroundPoster implements Runnable {    private final PendingPostQueue queue;    private final EventBus eventBus;    private volatile boolean executorRunning;    BackgroundPoster(EventBus eventBus) {        this.eventBus = eventBus;        queue = new PendingPostQueue();    }    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);            }        }    }}

  在BackgroundPoster 类中PendingPostQueue 是一个存储了PendingPost类型的队列,eventBus对应的就是EventBus类的实例,在BackgroundPoster 类中enqueue方法是在EventBus分发Post方法内部进行调用的;

 eventBus.getExecutorService()获取EventBus类中的ExecutorService,在源码我们可以发现ExecutorService=Executors.newCachedThreadPool();
 当执行eventBus.getExecutorService().execute(this);代码时,就跳转到BackgroundPoster 的run方法中
 @Override    public void run() {        try {            try {                while (true) {                    PendingPost pendingPost = queue.poll(1000);                    if (pendingPost == null) {                        synchronized (this) {                            // Check again, this time in synchronized                            pendingPost = queue.poll();                            if (pendingPost == null) {                                executorRunning = false;                                return;                            }                        }                    }                    eventBus.invokeSubscriber(pendingPost);                }            } catch (InterruptedException e) {                Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);            }        } finally {            executorRunning = false;        }    }

从run方法中可以看出,最终执行的还是eventBus.invokeSubscriber(pendingPost) 方法;

由浅入深了解EventBus:(六)