Android ViewRootImpl Choreographer SurfaceFlinger 学习笔记

本文详细探讨了Android中ViewRootImpl、Choreographer以及SurfaceFlinger的关键作用。首先,说明了DecorView与ViewRootImpl的关系,以及如何通过requestFitSystemWindows在ViewRootImpl中实现系统窗口适配。接着,分析了requestLayout在View和ViewRootImpl中的实现过程,揭示了布局更新的机制。最后,虽未直接涉及Choreographer,但其在UI帧同步中的重要性不言而喻,为Android流畅动画提供了基础。

一,每个DecorView对应一个ViewRootImpl,并且DecorView的mParent是ViewRootImpl。

二,View中requestFitSystemWindows的实现就是依赖于ViewRootImpl中的requestFitSystemWindows。可以参考http://blog.youkuaiyun.com/kobe_gong_5/article/details/45999713

In View.java

    public void requestFitSystemWindows() {
        if (mParent != null) {
            mParent.requestFitSystemWindows();
        }
    }


In ViewRootImpl.java

    @Override
    public void requestFitSystemWindows() { // 一直追溯到这里,调用scheduleTraversals才能完成relayout的具体操作
        checkThread();
        mApplyInsetsRequested = true;
        scheduleTraversals();
    }

三,View中requestLayout的实现也是依赖于ViewRootImpl中的requestLayout。

In View.java

    public void requestLayout() {
        if (mMeasureCache != null) mMeasureCache.clear();


        if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
            // Only trigger request-during-layout logic if this is the view requesting it,
            // not the views in its parent hierarchy
            ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null && viewRoot.isInLayout()) {
                if (!viewRoot.requestLayoutDuringLayout(this)) {
                    return;
                }
            }
            mAttachInfo.mViewRequestingLayout = this;
        }


        mPrivateFlags |= PFLAG_FORCE_LAYOUT;
        mPrivateFlags |= PFLAG_INVALIDATED;


        if (mParent != null && !mParent.isLayoutRequested()) {
            mParent.requestLayout();
        }
        if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
            mAttachInfo.mViewRequestingLayout = null;
        }
    }


In ViewRootImpl.java

    @Override
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread(); // 必须在ui线程中调用
            mLayoutRequested = true;
            scheduleTraversals();
        }
    }


<think> 我们正在讨论Android视图系统中的ViewRootImplViewRootImpl是连接窗口和视图系统的关键类,它负责管理视图树的测量、布局和绘制,同时也处理输入事件和与WindowManagerService的通信。 根据要求,我们需要详细解释ViewRootImpl的作用,并在最后提出3-5个相关问题。 作用详解: 1. 视图树的根:ViewRootImpl是视图树的根,它连接了DecorView和WindowManager。每个窗口(Activity、Dialog等)都有一个ViewRootImpl实例。 2. 负责视图的绘制流程:它触发视图树的measure、layout和draw过程。当需要更新视图时(如视图内容改变、窗口尺寸变化等),ViewRootImpl会调度执行这些流程。 3. 输入事件分发:ViewRootImpl接收来自输入系统的触摸事件、按键事件等,并将它们分发给视图树。 4. 与WindowManagerService通信:ViewRootImpl通过IWindowSession与WMS通信,负责窗口的添加、更新和删除,以及窗口属性的设置。 5. 管理Surface:ViewRootImpl负责创建和管理窗口的Surface,并在绘制时提供Canvas,最后将绘制内容提交到SurfaceFlinger进行合成和显示。 6. 同步垂直同步信号(VSync):通过Choreographer来接收VSync信号,确保绘制与显示刷新率同步,避免掉帧。 7. 窗口焦点管理:处理窗口焦点的获取和丢失。 我们将在回答中详细描述这些点,并给出一些代码片段来说明。最后,按照要求提出相关问题。 </think>### Android ViewRootImpl 核心作用解析 #### 1. ViewRootImpl 的核心定位 ```mermaid graph LR A[WindowManagerService] -->|窗口管理| B[ViewRootImpl] B -->|控制| C[DecorView] B -->|管理| D[Surface] B -->|调度| E[Choreographer] B -->|分发| F[InputEvent] ``` #### 2. 六大核心功能详解 | 功能领域 | 具体作用 | 关键方法/机制 | |------------------|--------------------------------------------------------------------------|----------------------------------------| | **视图树根节点** | 连接 DecorView 与 WindowManager 的桥梁 | `setView(View, WindowManager.LayoutParams)` | | **绘制调度中枢** | 协调整个视图树的测量(measure)、布局(layout)、绘制(draw)流程 | `performTraversals()` | | **输入事件网关** | 接收并分发所有硬件输入事件(触摸/按键) | `dispatchInputEvent(InputEvent)` | | **窗口通信代理** | 通过 Binder 与 WindowManagerService 通信 | `IWindowSession.addToDisplay()` | | **Surface 管理** | 创建/管理窗口的绘图表面(Surface),处理缓冲区交换 | `relayoutWindow()` 和 `draw()` | | **VSync 协调** | 通过 Choreographer 同步显示刷新信号 | `doFrame()` 回调 | #### 3. 核心工作流程源码解析 ```java // 核心调度方法 (ViewRootImpl.java) void performTraversals() { // 1. 窗口尺寸计算 int desiredWindowWidth = ...; int desiredWindowHeight = ...; // 2. 执行测量 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); // 3. 执行布局 performLayout(lp, desiredWindowWidth, desiredWindowHeight); // 4. 执行绘制 if (!cancelDraw) { performDraw(); } } // 测量阶段 private void performMeasure(int widthMeasureSpec, int heightMeasureSpec) { mView.measure(widthMeasureSpec, heightMeasureSpec); // 从DecorView开始 } // 绘制阶段核心 private void performDraw() { Surface surface = mSurface; Canvas canvas = surface.lockCanvas(dirty); try { mView.draw(canvas); // 触发整个视图树绘制 } finally { surface.unlockCanvasAndPost(canvas); // 提交到SurfaceFlinger } } ``` #### 4. 关键协作机制 1. **与 WMS 通信**: ```java // 窗口添加流程 mWindowSession.addToDisplay(mWindow, ...); // 通过IWindowSession ``` 2. **VSync 同步**: ```mermaid sequenceDiagram Choreographer->>ViewRootImpl: VSync 信号到达 ViewRootImpl->>ViewRootImpl: doFrame() ViewRootImpl->>ViewRootImpl: performTraversals() ``` 3. **输入事件处理**: ```java // InputEventReceiver 回调 public void onInputEvent(InputEvent event) { enqueueInputEvent(event, this, 0, true); } ``` #### 5. 特殊场景处理 - **窗口尺寸变化**: ```java void relayoutWindow(WindowManager.LayoutParams params) { // 与WMS协商新尺寸 int relayoutResult = mWindowSession.relayout(..., mSurface); // 更新Surface尺寸 if (mSurface.isValid()) { mSurface.setSize(newWidth, newHeight); } } ``` - **硬件加速控制**: ```java // 根据API级别和设备能力启用硬件加速 if (mAttachInfo.mHardwareRenderer != null) { canvas = mAttachInfo.mHardwareRenderer.lockCanvas(); } ``` - **内存泄漏防护**: ```java void die() { // 断开所有引用链 mSurface.release(); mView = null; mAttachInfo.mRootView = null; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值