一、postInvalidate
- 刷新界面,可以在任意线程中使用。
- 通过 Handler 切换到主线程,然后调用 View.invalidate 实现刷新。
二、invalidate
- 刷新界面,只能在主线程中使用。只会调用 onDraw 方法。
- 更新当前 View 的标志位,通过 do while 不断地向父容器请求刷新,更新父容器的标志位,直到最顶层的 ViewRootImpl。调用 scheduleTraversals 方法,通过 Handler 向 MessageQueue 插入一个同步屏障(标识当前任务的优先级最高),再 put 一个 Runnable 任务。最终会调用 ViewRootImp.performTravesals 方法,走三大流程的时候,通过标志位的判断,会跳过 onMeasure 和 onLayout,最终只会走 onDraw流程。
三、requestLayout
- 刷新界面,只能在主线程中调用。会重走绘制三大流程 onMeasure onLayout onDraw。
- 更新当前 View 的标志位,调用 parent.requestLayout,层层向上,最终调用到 ViewRootImpl.requestLayout 方法。在该方法内部,调用 scheduleTraversals 方法,通过 Handler 向 MessageQueue 插入一个同步屏障(标识当前任务的优先级最高),再 put 一个 Runnable 任务。最终会调用 ViewRootImpl.perfromTraversals 方法,重走绘制三大流程。
四、比较
1、同
- 都是用来刷新界面的
2、异
- invalidate 和 postInvalidate 方法只会调用 onDraw 方法;requestLayout 方法则会重新调用onMeasure、onLayout、onDraw。
- invalidate 只能在 主线程 调用,postInvalidate 可以在任意线程中调用。
五、参考资料
- https://blog.csdn.net/xw13782513621/article/details/73863006
- https://www.jianshu.com/p/ce30f200209e