大家在日常开发过程中,应该对invalidate,requestLayout简易的区别都理解,最近准备针对这两个问题问几问。
先来invalidate吧。
- invalidate 的执行流程是什么样子的?
- 如果连续调用多次invalidate执行流程是?
- invalidate重绘的区域是如何确定的,仅是当前View还是整个View树,还是某种计算方式?
- View除了invalidate()外,还有个方法叫做postInvalidateOnAnimation(),这两个方法有何区别?
更多问答 >>
-
每日一问 | RxJava中Observable、Flowable、Single、Maybe 有何区别?
2021-01-03 20:34 -
每日一问 | Java中匿名内部类写成 lambda,真的只是语法糖吗?
2021-01-11 00:00 -
每日一问 | Java 中的 lambda 与 Android 中的 lambda 有什么不同?
2021-01-31 17:20 -
每日一问 | Android 中两种设置线程优先级的方式,有何区别?
2021-01-27 23:59 -
2021-01-31 16:58
-
每日一问 | Call requires API level 23 (current min is 14) 扫描出来的原理是?
2020-12-27 22:39 -
每日一问 | 当Unsafe遇上final,超神奇的事情发生了?
2020-11-02 00:16 -
每日一问 | 属性动画与硬件加速的相遇,不是你想的那么简单?
2020-10-26 23:45 -
每日一问 | 关于 RecyclerView$Adapter setHasStableIds(boolean)的一切
2020-10-26 23:44 -
每日一问 | 玩转 Gradle,可不能不熟悉 Transform,那么,我要开始问了。
2020-10-26 23:45
先简答一下,周末再详细分析
invalidate
的执行流程是怎样的?它是如何确定Dirty Area的呢?跟之前的问题 "属性动画与硬件加速的相遇,不是你想的那么简单?" 差不多,invalidate
同样会根据硬件加速的开关状态来选择2套不同的处理方案。在硬件加速开启的情况下,invalidate
信号是通过Parent的onDescendantInvalidated
方法一级级往上传递,最后会在ViewRootImpl的onDescendantInvalidated
里向Choreographerpost
一个Traversal任务。并且Dirty Area是不用计算的,范围就是RootView的宽高。没有开启硬件加速的话,Dirty Area的计算就比较复杂了,它会根据View是否应用过Scale,Rotation等动画,还有Parent的ClipChildren属性来确定一个最大的区域,如果这个区域有跟其他View相交的话,比如像下图中的蓝色View:invalidateChild
方法中通过循环来一级一级调用Parent的invalidateChildInParent
向上传递,最后在ViewRootImpl里合并(在下一帧刷新之前,可能其他地方也有调用过invalidate
),合并之后发起Traversal。在同一方法内连续调用多次
多余的invalidate
会怎样?invalidate
会直接跳过。每次invalidate
都会更新mPrivateFlags
,比如加入PFLAG_INVALIDATED、去掉PFLAG_DRAWING_CACHE_VALID等,而在更新之前,会先检测这些标记是否已经更新过,如果是的话则不作处理。
跟之前的 别慌,你 post 一个 Runnable ,在下一帧就可以拿到了 里面提到的postInvalidateOnAnimation
方法原理?postOnAnimation
差不多,这个postInvalidateOnAnimation
方法会在下一次屏幕刷新时自动调用invalidate
。七个小时前,现在十点来算的话,凌晨3点....可怕
大佬都是这样彻夜学习的么
大佬的名字是小缘,为什么这么多年不是大缘?细思恐密。熬夜会永远停在那个夜晚。狗头。。。
先明确概念,invalidate不是重绘的意思,是废弃的意思。
绘制是下一次onDrow的事情,联系也没那么大。