为什么view.post()能保证获取到view的宽高?
- 业务需求代码开始时机一般是在:Activity的生命周期onCreate()
- 视图View 绘制时机:Activity的生命周期onResume()之后
- 业务需求代码需获取宽高的时机 跟 View的绘制时机 存在时序问题
- 一般来说,业务需求代码开始时就需要获取View的相关信息(如宽、高),但:View 绘制时机在Activity.onResume()之后,即在Activity.onCreate()之后 = 业务需求代码开始后。
总结
View.post()的原理:以Handler为基础,View.post() 将传入任务添加到 View绘制任务所在的消息队列尾部,从而保证View.post() 任务的执行时机是在View 绘制任务完成之后的。 其中,几个关键点:
1-View.post()实际操作:将view.post()传入的任务保存到一个数组里 /
2-View.post()添加的任务 添加到 View绘制任务所在的消息队列尾部的时机:View 绘制流程的开始阶段,即 ViewRootImpl.performTraversals()
3-View.post()添加的任务执行时机:在View绘制任务之后
- 当AttachInfo不为null时,直接调用其内部Handler的post;
- 当AttachInfo为null时,则将任务加入当前View的等待队列中。
通过View.post()添加的任务是在View绘制任务里 – 开始绘制阶段时添加到消息队列的尾部的;
所以,View.post() 添加的任务的执行是在View绘制任务后才执行,即在View绘制流程结束之后执行
即View.post() 添加的任务能够保证在所有 View绘制流程结束之后才被执行,所以 执行View.post() 添加的任务时可以正确获取到 View 的宽高。
参考文章
- https://blog.csdn.net/carson_ho/article/details/109282606
- https://www.cnblogs.com/dasusu/p/8047172.html
- https://blog.csdn.net/scnuxisan225/article/details/49815269