eventbus中handlerposter类进行分析
来源:互联网 发布:仙剑4for mac打不开 编辑:程序博客网 时间:2024/05/28 05:18
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 方法中取出队列中的消息,但是只取一个。
- eventbus中handlerposter类进行分析
- EventBus源码阅读(15)-HandlerPoster
- android中使用EventBus进行消息通知
- EventBus与RxJava使用与分析(陆续更新中)
- EventBus 2.4 源码分析
- EventBus源码注释分析
- EventBus使用与分析
- EventBus框架源码分析
- EventBus源码分析
- EventBus源码分析
- EventBus使用和分析
- EventBus 源码分析
- EventBus 源码分析
- EventBus的源码分析
- EventBus 3 源码分析
- EventBus 源码分析
- EventBus的源码分析
- EventBus源码分析
- TP FP TN FN
- VTK系统基础概念一
- LeetCode.299 Bulls and Cows
- 关于数据库的增删查改
- #!/bin/sh与#!/bin/bash
- eventbus中handlerposter类进行分析
- R-CNN
- android httpclient 设置超时
- 【前端】常用工具类网站总结
- AsyncTasktools
- 实验七:将menu设计为可重用的子系统
- 传球游戏
- js对文本框的特殊字符进行编译和反编译,过滤的效果,常用于文本输入防止xss
- Ubuntu 14.04 上安装 CUDA 7.5/8.0 超详细教程