eventbus中handlerposter类进行分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liu_jing_hui/article/details/78423046

EventBus中的HandlerPoster类进行分析

HandlerPoster初始化的进行分析

mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
参数一:eventbus对象  参数二:当前操作的线程 参数三:最大的处理消息数

我们点击进入HandlerPoster这个类我们可以发现它继承的是Handler

我们可以查看一下HandlerPoster这个构造函数类里面的源码编写

 HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();
    }

HandlerPoster中的enqueue的方法进行源码分析

 void enqueue(Subscription subscription, Object event) {
        //通过注册事件和信息来获取PendingPost
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            //handlerActive是一个标志位,标志当前是否正在执行处理PendingPostQueue队列中的PendingPost,也就是正在调用队列中的注册方法
            if (!handlerActive) {
                handlerActive = true;
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
            }
        }
    }

这段代码进行分析一下,首先通过注册信息和事件对象PendingPost对象,然后发送消息通过Handler通知自身的handleMessage方法进行执行。这里的handlerActive是一个标志位,标志当前是否正在执行PendingPostQueue队列中的PendingPost,也就是正在调用的队列中的注册方法。

(1)handlerActive这个在类的初始化的源码查看

    private boolean handlerActive;这里就是初始化一个变量,没有做任何赋值的操作,默认值是false

(2)PendingPost.obtainPendingPost(subscription, event);这个里面的源码进行分析

static PendingPost obtainPendingPost(Subscription subscription, Object event) {
    synchronized (pendingPostPool) {
        int size = pendingPostPool.size();
        if (size > 0) {
            PendingPost pendingPost = pendingPostPool.remove(size - 1);
            pendingPost.event = event;
            pendingPost.subscription = subscription;
            pendingPost.next = null;
            return pendingPost;
        }
    }
    return new PendingPost(event, subscription);
}

我们可以看到他这里只是做了一个赋值的操作。

HandlerPoster类整体的进行在分析,和注释的添加

final class HandlerPoster extends Handler {
    //队列,即将执行的Post
    private final PendingPostQueue queue;
    //一个Post最大的在HandleMessage中的时间
    private final int maxMillisInsideHandleMessage;
    private final EventBus eventBus;
    //handler是否运行起来了
    private boolean handlerActive;

    HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
        this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
        queue = new PendingPostQueue();
    }

    void enqueue(Subscription subscription, Object event) {
        //PendingPost维护了一个可以复用PendingPost对象的复用池
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            //加入到队列中
            queue.enqueue(pendingPost);
            //如果handleMessage没有运行起来
            if (!handlerActive) {
                handlerActive = true;
                //发送一个空消息,让handleMessage运行起来
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
            }
        }
    }

    @Override
    public void handleMessage(Message msg) {
        boolean rescheduled = false;
        try {
            long started = SystemClock.uptimeMillis();
            while (true) {
                //从队列中取出PendingPost
                PendingPost pendingPost = queue.poll();
                if (pendingPost == null) {
                    synchronized (this) {
                        // Check again, this time in synchronized
                        pendingPost = queue.poll();
                        if (pendingPost == null) {
                            handlerActive = false;
                            return;
                        }
                    }
                }
                //调用eventBus的方法,分发消息
                eventBus.invokeSubscriber(pendingPost);
                long timeInMethod = SystemClock.uptimeMillis() - started;
                //如果再一定时间内都还没有将队列排空,则退出
                if (timeInMethod >= maxMillisInsideHandleMessage) {
                    if (!sendMessage(obtainMessage())) {
                        throw new EventBusException("Could not send handler message");
                    }
                    rescheduled = true;
                    return;
                }
            }
        } finally {
            handlerActive = rescheduled;
        }
    }
}

PendingPost数据结构:

final class PendingPost {
    Object event;//事件
    Subscription subscription;//订阅
    PendingPost next;//与队列的数据结构有关,指向下一个节点
}

其中PendingPost维护着一个可以复用PendingPost对象的复用池,通过obtainPendingPost(Subscription, Object)方法复用,通过releasePendingPost(PendingPost)方法回收。

handleMessage() 中有一个死循环,这个死循环不停的从队列中拿数据,然后通过 EventBus.invokeSubscriber() 分发出去。每分发完一次比对一下时间,如果超过了 maxMillisInsideHandleMessage ,那么发送空 message 再次进入到 handlerMessage 中且退出本次循环。 这样做的原因是不要阻塞的UI线程(??)

BackgroundPoster

同理 BackgroundPoster ,只不过 HandlerPoster 是在 handlerMessage 中进行分发操作,而 BackgroundPoster 是在 Runnable 的 run 方法中将所有队列中的消息取出进行分发,直到取完为止。

AsyncPoster

而 AsyncPoster 虽然也是在 Runnable 的 run 方法中取出队列中的消息,但是只取一个。

猜你喜欢

转载自blog.csdn.net/liu_jing_hui/article/details/78423046
今日推荐