美文网首页
View刷新UI路径

View刷新UI路径

作者: tzlf | 来源:发表于2020-01-18 10:41 被阅读0次

View调用 invalidate() 或 postInvalidate() 刷新UI界面,对应android 8.0

先介绍通知刷新的重要变量ViewParent mParent及其赋值过程,再介绍刷新流程

1. 首先看一张图:

ViewGroup和ViewRootImpl 实现了接口ViewParent

可以看到View 有变量 ViewParent mParent , 所有继承 View 的 子类都有 mParent 

每个View或ViewGroup的mParent 指向包含自身的父类ViewGroup

而顶层 DecorView(大部分)的mParent 则指向 ViewRootImpl

2. 接下来是View或ViewGroup如何关联到对应的ViewParent mParent

frameworks/base/core/java/android/view/View.java

其内部函数 assignParent:

frameworks/base/core/java/android/view/ViewGroup.java

addView --> addViewInner   --> assignParent 

所以在调用 ViewGroup的addView时,会绑定ViewParent mParent

3. 顶层DecorView如何关联到ViewRootImpl

frameworks/base/core/java/com/android/internal/policy/DecorView.java

frameworks/base/core/java/android/view/ViewRootImpl.java

setView函数的第一个参数就是DecorView(大部分都是),这个函数调用参考WindowManagerGlobal.addView()

4.View通知刷新流程

frameworks/base/core/java/android/view/View.java

invalidate() --> invalidate(true) --> invalidateInternal() --> invalidateChild()

frameworks/base/core/java/android/view/ViewGroup.java

invalidateChild -->invalidateChildInParent(ViewGroup)

-->invalidateChildInParent(FrameLayout)

-->invalidateChildInParent(DecorView)

--> invalidateChildInParent(ViewRootImpl)

从最底层View一路传递到顶层的DecorView,最终调用ViewRootImpl的 invalidateChildInParent函数

frameworks/base/core/java/android/view/ViewRootImpl.java

invalidateChildInParent() --> invalidateRectOnScreen() --> scheduleTraversals ()--> TraversalRunnable --> doTraversal() --> performTraversals()

performTraversals函数开始界面刷新。

5.非UI线程调用postInvalidate刷新,实质是往UI线程发送刷新消息,ViewRootImpl中ViewRootHandler绑定的就是主线程

frameworks/base/core/java/android/view/View.java

postInvalidate -->  postInvalidateDelayed  --> dispatchInvalidateDelayed

frameworks/base/core/java/android/view/ViewRootImpl.java

最终还是调用 View.invalidate , 不过此时已经切换到UI线程

相关文章

网友评论

      本文标题:View刷新UI路径

      本文链接:https://www.haomeiwen.com/subject/aelkzctx.html