App StartingWindow分析

打开WMS的staring window日志
设置WindowManagerDebugConfig的
static final boolean DEBUG_STARTING_WINDOW = true;

从log和代码分析
1.setAppStartingWindow
首先针对主题进行检查 有一些主题下是不能显示startingwindow的

final boolean windowIsTranslucent = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowIsTranslucent, false);
                final boolean windowIsFloating = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowIsFloating, false);
                final boolean windowDisableStarting = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowDisablePreview, false);

如上面三种
另外对于设置了
final boolean windowShowWallpaper = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false); 以背景为壁纸
还要设置
windowFlags |= FLAG_SHOW_WALLPAPER

检查完主题之后 根据主题设置依稀样式相关的数据 保存在StartingData 数据结构里面,然后抛出消息给mH所在线程处理

wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                    labelRes, icon, logo, windowFlags);
  Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
            // Note: we really want to do sendMessageAtFrontOfQueue() because we
            // want to process the message ASAP, before any other queued
            // messages.
            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
            mH.sendMessageAtFrontOfQueue(m);

设置AppWindowToken.startingView 为创建的decorview

2.处理过程case ADD_STARTING
通过日志可以分析 首先创建window和viww 通过PhoneWindowManager创建window 和viewRoot,并且addWindow到WMS,
创建WindowState和surface数据 整个过程可以根据log看出

mPolicy.addStartingWindow(wtoken.token, sd.pkg, sd.theme,
                            sd.compatInfo, sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo,
                            sd.windowFlags, overrideConfig);
 12-29 08:30:31.314 31101-32230/system_process V/WindowManager: setAppStartingWindow: token=Token{5108b27 ActivityRecord{cea59e6 u0 com.android.providers.downloads.ui/.activity.InterDownloadTaskDetailActivity t4}} pkg=com.android.providers.downloads.ui transferFrom=null
12-29 08:30:31.314 31101-32230/system_process V/WindowManager: Checking theme of starting window: 0x100d0017
12-29 08:30:31.314 31101-32230/system_process V/WindowManager: Translucent=false Floating=false ShowWallpaper=false
12-29 08:30:31.314 31101-32230/system_process V/WindowManager: Creating StartingData
12-29 08:30:31.314 31101-32230/system_process V/WindowManager: Enqueueing ADD_STARTING
  1. 之后的阶段就是有过几次事务状态变化,但是mDrawState=DRAW_PENDING 不做任何处理,直到客户端最后调用mWindowSession.finishDrawing(mWindow) 周后才会对动画状态进行切换,切换到COMMIT_DRAW_PENDING
12-29 08:30:31.344 31101-32230/system_process I/WindowManager: commitFinishDrawingLocked: Window{4730896 u0 Starting com.android.providers.downloads.ui} cur mDrawState=DRAW_PENDING
12-29 08:30:31.344 31101-32230/system_process D/WindowManager: updateWindows: starting Window{4730896 u0 Starting com.android.providers.downloads.ui} isOnScreen=false allDrawn=false freezingScreen=false
12-29 08:30:31.358 31101-32230/system_process I/WindowManager: commitFinishDrawingLocked: Window{4730896 u0 Starting com.android.providers.downloads.ui} cur mDrawState=DRAW_PENDING
12-29 08:30:31.358 31101-32230/system_process D/WindowManager: updateWindows: starting Window{4730896 u0 Starting com.android.providers.downloads.ui} isOnScreen=false allDrawn=false freezingScreen=false
12-29 08:30:31.360 31101-31218/system_process V/WindowManager: Finishing drawing window Window{4730896 u0 Starting com.android.providers.downloads.ui}: mDrawState=DRAW_PENDING

4 这是在进行事务处理的时候就会有所变化,切换到READY_TO_SHOW状态,但是由于现在app还没有准备好 mAppTransition.isReady() ==false 还不能绘制

12-29 08:30:31.360 31101-31218/system_process V/WindowManager: Draw state now committed in Window{4730896 u0 Starting com.android.providers.downloads.ui}
12-29 08:30:31.361 31101-31218/system_process I/WindowManager: commitFinishDrawingLocked: Window{4730896 u0 Starting com.android.providers.downloads.ui} cur mDrawState=COMMIT_DRAW_PENDING

12-29 08:30:31.362 31101-31218/system_process V/WindowManager: performShow on WindowStateAnimator{7e561ed Starting com.android.providers.downloads.ui}: mDrawState=READY_TO_SHOW readyForDisplay=false starting=true 
during animation: policyVis=true attHidden=false tok.hiddenRequested=true tok.hidden=true animating=false tok animating=false Callers=com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:631 com.android.server.wm.WindowSurfacePlacer.applySurfaceChangesTransaction:761 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementInner:324 

12-29 08:30:31.362 31101-31218/system_process D/WindowManager: updateWindows: starting Window{4730896 u0 Starting com.android.providers.downloads.ui} isOnScreen=false allDrawn=false freezingScreen=false
12-29 08:30:31.365 31101-32230/system_process I/WindowManager: commitFinishDrawingLocked: Window{4730896 u0 Starting com.android.providers.downloads.ui} cur mDrawState=READY_TO_SHOW

5 直到handleAppTransitionReadyLocked被调用之后 app才准备好 readyForDisplay,就可以把状态切换为HAS_DRAWN
mDrawState = HAS_DRAWN

12-29 08:30:31.373 31101-32230/system_process V/WindowManager: performShow on WindowStateAnimator{7e561ed Starting com.android.providers.downloads.ui}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=true during animation: policyVis=true attHidden=false tok.hiddenRequested=false tok.hidden=false animating=false tok animating=false Callers=com.android.server.wm.AppWindowAnimator.showAllWindowsLocked:458 com.android.server.wm.WindowSurfacePlacer.handleOpeningApps:1263 com.android.server.wm.WindowSurfacePlacer.handleAppTransitionReadyLocked:1197 

6 真正的window启动之后,就会改变windowState的mAttrs.type 变成非TYPE_APPLICATION_STARTING的,
执行void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator)方法
该方法会把 方法哦WMS的mFinishString队列中 之后发送消息

void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
        firstWindowDrawn = true;

        // We now have a good window to show, remove dead placeholders
        removeAllDeadWindows();

        if (startingData != null) {
            if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
                    + win.mToken + ": first real window is shown, no animation");
            // If this initial window is animating, stop it -- we will do an animation to reveal
            // it from behind the starting window, so there is no need for it to also be doing its
            // own stuff.
            winAnimator.clearAnimation();
            winAnimator.mService.mFinishedStarting.add(this);
            winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
        }
        updateReportedVisibilityLocked();
    }
12-29 08:30:31.486 31101-31218/system_process V/WindowManager: Finish starting AppWindowToken{8089f7d token=Token{5108b27 ActivityRecord{cea59e6 u0 com.android.providers.downloads.ui/.activity.InterDownloadTaskDetailActivity t4}}}: first real window is shown, no animation

7 之后WMS处理消息 case FINISHED_STARTING:
调用mPolicy.removeStartingWindow(token, view) 移除window

8 最后destorySurface的时候清理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值