天天看點

android window體系_2.window視窗管理

window的類型定義在WindowManager檔案裡面,檔案路徑:

frameworks/base/core/java/android/view/WindowManager.java
1.window類型

1.1 一般應用類型

type的取值範圍是1-99

// 一般應用,
public static final int TYPE_APPLICATION        = 2;
// 啟動應用時的startingwindow
public static final int TYPE_APPLICATION_STARTING = 3;
// 
public static final int TYPE_DRAWN_APPLICATION = 4;
           

1.2 子視窗類型

type的取值範圍是1000-1999

public static final int FIRST_SUB_WINDOW = 1000;
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;
public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2;
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3;
public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW + 4;
           

1.3 系統視窗類型

type的取值範圍是2000-2999

public static final int FIRST_SYSTEM_WINDOW     = 2000;
// status bar
public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;
public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;
public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
// 總是顯示在應用window視窗的上面
public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
// keyguard
public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
// toast
public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
// input method
public static final int TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11;
// input method dialog
public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12;
// wallpaper
public static final int TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13;
public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16;
// navigation bar
public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;
// volumn level
public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;
// voice interaction
public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;
           
2.window視窗管理

其中比較特殊的視窗有wallpaper/input method/status bar/navigation bar

最終決定視窗層級的是getWindowLayerFromTypeLw方法

default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
            return APPLICATION_LAYER;
        }

        switch (type) {
            case TYPE_WALLPAPER:
                // wallpaper is at the bottom, though the window manager may move it.
                return  1;
            case TYPE_PRESENTATION:
            case TYPE_PRIVATE_PRESENTATION:
                return  APPLICATION_LAYER;
            case TYPE_DOCK_DIVIDER:
                return  APPLICATION_LAYER;
            case TYPE_QS_DIALOG:
                return  APPLICATION_LAYER;
            case TYPE_PHONE:
                return  3;
            case TYPE_SEARCH_BAR:
            case TYPE_VOICE_INTERACTION_STARTING:
                return  4;
            case TYPE_VOICE_INTERACTION:
                // voice interaction layer is almost immediately above apps.
                return  5;
            case TYPE_INPUT_CONSUMER:
                return  6;
            case TYPE_SYSTEM_DIALOG:
                return  7;
            case TYPE_TOAST:
                // toasts and the plugged-in battery thing
                return  8;
            case TYPE_PRIORITY_PHONE:
                // SIM errors and unlock.  Not sure if this really should be in a high layer.
                return  9;
            case TYPE_SYSTEM_ALERT:
                // like the ANR / app crashed dialogs
                // Type is deprecated for non-system apps. For system apps, this type should be
                // in a higher layer than TYPE_APPLICATION_OVERLAY.
                return  canAddInternalSystemWindow ? 13 : 10;
            case TYPE_APPLICATION_OVERLAY:
                return  12;
            case TYPE_DREAM:
                // used for Dreams (screensavers with TYPE_DREAM windows)
                return  14;
            case TYPE_INPUT_METHOD:
                // on-screen keyboards and other such input method user interfaces go here.
                return  15;
            case TYPE_INPUT_METHOD_DIALOG:
                // on-screen keyboards and other such input method user interfaces go here.
                return  16;
            case TYPE_STATUS_BAR:
                return  17;
            case TYPE_STATUS_BAR_PANEL:
                return  18;
            case TYPE_STATUS_BAR_SUB_PANEL:
                return  19;
            case TYPE_KEYGUARD_DIALOG:
                return  20;
            case TYPE_VOLUME_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  21;
            case TYPE_SYSTEM_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  canAddInternalSystemWindow ? 22 : 11;
            case TYPE_NAVIGATION_BAR:
                // the navigation bar, if available, shows atop most things
                return  23;
            case TYPE_NAVIGATION_BAR_PANEL:
                // some panels (e.g. search) need to show on top of the navigation bar
                return  24;
            case TYPE_SCREENSHOT:
                // screenshot selection layer shouldn't go above system error, but it should cover
                // navigation bars at the very least.
                return  25;
            case TYPE_SYSTEM_ERROR:
                // system-level error dialogs
                return  canAddInternalSystemWindow ? 26 : 10;
            case TYPE_MAGNIFICATION_OVERLAY:
                // used to highlight the magnified portion of a display
                return  27;
            case TYPE_DISPLAY_OVERLAY:
                // used to simulate secondary display devices
                return  28;
            case TYPE_DRAG:
                // the drag layer: input for drag-and-drop is associated with this window,
                // which sits above all other focusable windows
                return  29;
            case TYPE_ACCESSIBILITY_OVERLAY:
                // overlay put by accessibility services to intercept user interaction
                return  30;
            case TYPE_SECURE_SYSTEM_OVERLAY:
                return  31;
            case TYPE_BOOT_PROGRESS:
                return  32;
            case TYPE_POINTER:
                // the (mouse) pointer layer
                return  33;
            default:
                Slog.e("WindowManager", "Unknown window type: " + type);
                return APPLICATION_LAYER;
        }
    }
           

一個普通應用的window層級如下:

android window體系_2.window視窗管理
關于X、Y、Z軸說明: 以螢幕的左上角為原點,橫向為X軸,豎向為Y軸,面向使用者的為Z軸。

我們看到的手機界面,其實是多個視窗混合繪制而成的

執行adb shell dumpsys window windows

Window #0 Window{faf8f8 u0 NavigationBar0}:
    mDisplayId=0 stackId=0 mSession=Session{f358093 1621:u0a10087} mClient=android.os.BinderProxy@c76fb6a
    mAttrs={(0,0)(fillxfill) sim={adjust=pan} ty=NAVIGATION_BAR fmt=TRANSLUCENT
    Requested w=1080 h=126 mLayoutSeq=91
    WindowStateAnimator{b7eb9ee NavigationBar0}:
       mAnimationIsEntrance=true      Surface: shown=true layer=0 alpha=1.0 rect=(0.0,0.0) 1080 x 126 transform=(1.0, 0.0, 1.0, 0.0)
  Window #1 Window{e4946e6 u0 StatusBar}:
    mDisplayId=0 stackId=0 mSession=Session{f358093 1621:u0a10087} mClient=android.os.BinderProxy@f9a9028
    mAttrs={(0,0)(fillx63) gr=TOP CENTER_VERTICAL sim={adjust=resize} layoutInDisplayCutoutMode=always ty=STATUS_BAR fmt=TRANSLUCENT
    Requested w=1080 h=63 mLayoutSeq=91
    mHasSurface=true isReadyForDisplay()=true mWindowRemovalAllowed=false
    WindowStateAnimator{b4b851c StatusBar}:
      Surface: shown=true layer=0 alpha=1.0 rect=(0.0,0.0) 1080 x 63 transform=(1.0, 0.0, 1.0, 0.0)
  Window #2 Window{4f91016 u0 AssistPreviewPanel}:
    mDisplayId=0 stackId=0 mSession=Session{f358093 1621:u0a10087} mClient=android.os.BinderProxy@af509d8
    mAttrs={(0,0)(fillx656) gr=BOTTOM START CENTER sim={state=unchanged adjust=nothing} ty=VOICE_INTERACTION_STARTING fmt=TRANSLUCENT
    Requested w=0 h=0 mLayoutSeq=14
    WindowStateAnimator{15e6525 AssistPreviewPanel}:
      mShownAlpha=0.0 mAlpha=1.0 mLastAlpha=0.0
  Window #3 Window{ac979a8 u0 DockedStackDivider}:
    mDisplayId=0 stackId=0 mSession=Session{f358093 1621:u0a10087} mClient=android.os.BinderProxy@7a8809a
    mAttrs={(0,0)(fillx126) sim={adjust=pan} layoutInDisplayCutoutMode=always ty=DOCK_DIVIDER fmt=TRANSLUCENT
    Requested w=1080 h=126 mLayoutSeq=91
    WindowStateAnimator{7a086fa DockedStackDivider}:
      mShownAlpha=0.0 mAlpha=1.0 mLastAlpha=0.0
  Window #4 Window{b2cf945 u0 com.example.myapplication/com.example.myapplication.MainActivity}:
    mDisplayId=0 stackId=2 mSession=Session{acdb18e 3003:u0a10101} mClient=android.os.BinderProxy@6e555bc
    mAttrs={(0,0)(fillxfill) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION wanim=0x10302fe
    Requested w=1080 h=1920 mLayoutSeq=91
    WindowStateAnimator{7d5d4ab com.example.myapplication/com.example.myapplication.MainActivity}:
      Surface: shown=true layer=0 alpha=1.0 rect=(0.0,0.0) 1080 x 1920 transform=(1.0, 0.0, 1.0, 0.0)
  Window #5 Window{1aa88c3 u0 com.android.launcher3/com.android.launcher3.Launcher}:
    mDisplayId=0 stackId=0 mSession=Session{cc98fd4 2067:u0a10081} mClient=android.os.BinderProxy@f359c72
    mAttrs={(0,0)(fillxfill) sim={adjust=pan} layoutInDisplayCutoutMode=always ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x10302f1
    Requested w=1080 h=1920 mLayoutSeq=77
    WindowStateAnimator{6b52ea1 com.android.launcher3/com.android.launcher3.Launcher}:
  Window #6 Window{3d68ba7 u0 com.android.systemui.ImageWallpaper}:
    mDisplayId=0 stackId=0 mSession=Session{f358093 1621:u0a10087} mClient=android.os.BinderProxy@ffe0c66
    mAttrs={(0,0)(2160x1920) gr=TOP START CENTER layoutInDisplayCutoutMode=always ty=WALLPAPER fmt=RGBX_8888 wanim=0x103030e
    Requested w=2160 h=1920 mLayoutSeq=80
    WindowStateAnimator{e018c6 com.android.systemui.ImageWallpaper}:
      Surface: shown=false layer=0 alpha=1.0 rect=(0.0,0.0) 2160 x 1920 transform=(1.0, 0.0, 1.0, 0.0)
           

從這個指令可以看,列印的結果和前面的那個圖一樣,按Z order從高到低

詳細的參考老羅的blog

https://blog.csdn.net/Luoshengyang/article/details/8498908

https://blog.csdn.net/Luoshengyang/article/details/8526644

https://blog.csdn.net/Luoshengyang/article/details/8550820添加連結描述