打開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{
5108 b27 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
之后的階段就是有過幾次事務狀態變化,但是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{
7e561 ed 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{
7e561 ed 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 placeholdersremoveAllDeadWindows();
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{
8089 f7d token=Token{
5108 b27 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的時候清理
總結
以上是生活随笔 為你收集整理的App StartingWindow分析 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。