Android Framework 之 Window / Win
2022-11-17 本文已影响0人
行走中的3卡
Android Framework 之 Window / WindowManager基本概念及addView源码分析
前一篇文章介绍了Window/WindowManager 以及它和View、ViewRootImpl 的基本概念,
也介绍了 WindowManager.addView 大体流程.
现介绍 WindowManager.updateViewLayout 的大体流程
1. WindowManager.updateViewLayout 更新
源码:WindowManagerGlobal.java
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
view.setLayoutParams(wparams);
synchronized (mLock) {
int index = findViewLocked(view, true);
ViewRootImpl root = mRoots.get(index);
mParams.remove(index);
mParams.add(index, wparams);
root.setLayoutParams(wparams, false);
}
分析:
(1) 根据传入的view 找到它在 mView 数组中的index
(2) 根据index 查找到view 对应的 ViewRootImpl 对象
(3) 根据index 从 mParams 数组中删除该View 的 布局参数, 并重新更新 布局参数
(4) 根据新的 布局参数wparams, 调用 ViewRootImpl 对象的 setLayoutParams 进行更新
下面看看 ViewRootImpl.setLayoutParams 源码
@VisibleForTesting
public void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
...
if (newView) {
mSoftInputMode = attrs.softInputMode;
requestLayout();
}
...
scheduleTraversals();
}
分析:
(1) 如果是 newView , 则会调用 requestLayout 执行刷新请求
(2) scheduleTraversals 方法会对 View 重新测量,布局,重绘。
除了 View 本身的重绘外,ViewRootImpl 还会通过 WindowSession 来更新 Window 视图,
这个过程是由 WindowManagerService 的 relayoutWindow来实现的,这同样也是一个 IPC 过程。
参考文献:
Android SDK API32 源码
https://juejin.cn/post/7076274407416528909#heading-25