Android窗口显示流程浅析(二)

本文深入探讨Android窗口显示流程,从ViewRootImpl的setView开始,详细阐述了向WMS添加窗口、建立SurfaceFlinger链接的过程,重点分析了WindowState、SurfaceSession和SurfaceComposerClient的关键步骤。
摘要由CSDN通过智能技术生成

上一篇我们看到了ViewRootImpl的setView函数,ViewRootImpl的setView函数,主要流程分为两步:

1.向WMS请求添加窗口并建立SurfaceFlinger链接

2.APP端请求获取Surface,WMS建立SurfaceControl等等。

本篇代码基于原生Android Q

一.显示过程概览

老规矩,先上图:

二. 核心代码流程

1.ViewRootImpl.setView

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        //......
                // Schedule the first layout -before- adding to the window
                // manager, to make sure we do the relayout before receiving
                // any other events from the system.
                requestLayout();//请求surface,建立SurfaceControl,获取surfaceFlinger的gbp对象
                
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                  //向WMS申请添加窗口,建立WindowsState,SurfaceSession,SurfaceComposerClient等核心对象
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel,
                            mTempInsets);
                    setFrame(mTmpFrame);
                } 
        //......
    }

从执行流程来说,本篇先介绍addToDisplay方法

2.Session里面会调用WMS的addWindow方法,该方法中有以下几处关键的逻辑:

    2.1 校验窗口是否重复添加,校验窗口的类型,校验窗口token的有效性

if (mWindowMap.containsKey(client.asBinder())) {  //校验重复添加
                Slog.w(TAG_WM, "Window " + client + " is already added");
                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
            }

            if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { //校验子窗口类型
                parentWindow = windowForClientLocked(null, attrs.token, false);
                if (parentWindow == null) {
                    Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
                          + attrs.token + ".  Aborting.");
                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                }
                if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
                        && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
                    Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
                            + attrs.token + ".  Aborting.");
                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                }
            }

            if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
                Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display.  Aborting.");
                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
            }

            AppWindowToken atoken = null;
            final boolean hasParent = parentWindow != null;
            // Use existing parent window token for child windows since they go in the same token
            // as there parent window so we can apply the s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值