窗口布局流程 - 安卓R

窗口布局简介

在安卓的窗口管理系统中,经常要执行的一个操作是布局。

布局会做许多事情,例如更新焦点窗口、调整所有的窗口位置、设置wallpaperTarget以显示或隐藏壁纸、开始过渡动画等。

很多时候都需要进行窗口的布局,例如View的Surface创建流程中调用WindowManagerService的relayoutWindow方法时、窗口创建时、窗口销毁时、窗口可见性变化时等。

布局流程

窗口布局流程一般从frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java的performSurfacePlacement方法开始:

    final void performSurfacePlacement() {
   
        performSurfacePlacement(false /* force */);
    }

    final void performSurfacePlacement(boolean force) {
   
        if (mDeferDepth > 0 && !force) {
   
            mDeferredRequests++;
            return;
        }
        int loopCount = 6;
        do {
   
            mTraversalScheduled = false;
            performSurfacePlacementLoop();
            mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
            loopCount--;
        } while (mTraversalScheduled && loopCount > 0);
        mService.mRoot.mWallpaperActionPending = false;
    }

这里有一个循环,循环限制了最多循环6次。可以发现在窗口布局时,不能确保一次完成布局,可能会重复布局多次。这里循环体内主要是调用了WindowSurfacePlacer的performSurfacePlacementLoop方法:

    private void performSurfacePlacementLoop() {
   
        if (mInLayout) {
   
            if (DEBUG) {
   
                throw new RuntimeException("Recursive call!");
            }
            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
                    + Debug.getCallers(3));
            return;
        }

        // TODO(multi-display):
        final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
        if (defaultDisplay.mWaitingForConfig) {
   
            // Our configuration has changed (most likely rotation), but we
            // don't yet have the complete configuration to report to
            // applications.  Don't do any window layout until we have it.
            return;
        }

        if (!mService.mDisplayReady) {
   
            // Not yet initialized, nothing to do.
            return;
        }

        mInLayout = true;

        if (!mService.mForceRemoves.isEmpty()) {
   
            // Wait a little bit for things to settle down, and off we go.
            while (!mService.mForceRemoves.isEmpty()) {
   
                final WindowState ws = mService.mForceRemoves.remove(0);
                Slog.i(TAG, "Force removing: " + ws);
                ws.removeImmediately();
            }
            Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
            Object tmp = new Object();
            synchronized (tmp) {
   
                try {
   
                    tmp.wait(250);
                } catch (InterruptedException e) {
   
                }
            }
        }

        try {
   
            mService.mRoot.performSurfacePlacement();

            mInLayout = false
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值