一、View.post
-
在主线程中使用。在 measure 执行后被调用,故在 onCreate 中使用可获取 View 真实的宽高。
-
post 方法中分两种情况:AttachInfo 不为空,直接调用 Handler.post 方法;AttachInfo 为空,将 Runnable 添加到等待队列 HandlerActionQueue 中。(AttachInfo 持有 Handler 对象)
-
AttachInfo 的赋值在 View.dispatchAttachedToWindow 中。
-
dispatchAttachedToWindow 的调用在 ViewRootImpl.performTraversals。
-
ViewRootImp.performTraversals 还会调用 HandlerActionQueue.executeActions 将等待队列中的 Runnable 通过 Handler.post 添加到主线程的执行队列中。
-
等主线程正在执行的 Runnable 任务(TraversalRunnable:绘制三大流程)结束,就会执行我们 post 的 Runnable 任务。
-
故,在绘制流程开始阶段,通过 View.post 的任务被添加到主线程的执行队列中;绘制流程结束后,相关任务被执行。此时便可以获取到 View 正确的宽高。
-
参考资料:
https://blog.csdn.net/jdsjlzx/article/details/107397163
https://blog.csdn.net/jdsjlzx/article/details/107397163
二、Handler.post
- 调用 MessageQueue.enqueueMessage 方法将当前 Runnable 插入执行队列中。执行队列按 delay 的时间大小从低到高排列,延迟时间短的放在前面,延迟时间长的放在后面。
三、比较
1、同
- 将消息传递到主线程,执行一定的操作
2、异
- 在 onCreate 中,Handler.post 的任务的执行时间等同于该行代码的执行时间;View.post 的任务的执行时间在 measure 之后,可获取 View 真实的宽高。