带你从app入口到对话框到悬浮窗剖析android-UI层级系列一

起源:前几天一个网友问我,他有个需求在来电的时候弹窗提示信息—使用WindowManager.addView(),但是遇到360之类的系统安全APP也会弹窗提示,会被其他的弹窗盖住,使用TYPE_SYSTEM_ALERT类型过后,有的手机会有的机器不会,然后我突然想起既然大都是这种方式添加的弹窗,我们能不能获取到其他APP的弹窗View呢,如果能获取到,那么可以将之移除 *_*,哇咔咔咔~太坏了。

经过几天的资料查找和源码分析,重点查看了android的窗口管理方面(涉及到的类和接口:ViewManager,WindowManager,WindowManagerImpl,WindowManagerPolicy,WindowManager,WindowManager.LayoutParams,CompatModeWrapper,DecorView,ViewRootImpl,Window,PhoneWindow,PolicyManager,ActivityThread等等还有其他很多),还是找到一些蛛丝马迹。

当然,这篇文章的重点不在于最终是否能将其他APP的弹窗给删除掉,而是可以一种学习方式,有所想有所学。从这个思路去探测源码内部的世界到底怎么样~~

好了,接下来开始踏步走...

既然是UI层级,当然就会涉及到覆盖问题。你想想,从系统启动到桌面到APP启动,android的UI变化等等,以及我们APP的layout里面,一层一层的,android是如何控制的呢?还有你看到的状态栏StatusBar,状态栏下滑出现的系统抽屉(notifications栏列表之类的),以及一些没有实体键的手机的虚拟按键之类的。

先上几张图简单看一下...

带你从app入口到对话框到悬浮窗剖析android-UI层级系列一_第1张图片带你从app入口到对话框到悬浮窗剖析android-UI层级系列一_第2张图片带你从app入口到对话框到悬浮窗剖析android-UI层级系列一_第3张图片带你从app入口到对话框到悬浮窗剖析android-UI层级系列一_第4张图片


先去吃个饭,回来继续.....


---------------------------吃完了-----------------------------继续---------------------------------


接着再介绍一些后续需要涉及到的东西:android窗口类型字段,位于android.view.WindowManager.LayoutParams中,这是一个静态内部类,继承自ViewGroup.LayoutParams,用于WindowManager.addView()添加的view布局。其中有一个字段public int type,这个字段表示的就是当前添加的View是属于什么类型的窗口(关于窗口,后续内容会依次提到相关知识)。

	public int type;
	/**
         * Start of window types that represent normal application windows.
         */
        public static final int FIRST_APPLICATION_WINDOW = 1;
        
        /**
         * Window type: an application window that serves as the "base" window
         * of the overall application; all other application windows will
         * appear on top of it.
         */
        public static final int TYPE_BASE_APPLICATION   = 1;
        
        /**
         * Window type: a normal application window.  The {@link #token} must be
         * an Activity token identifying who the window belongs to.
         */
        public static final int TYPE_APPLICATION        = 2;
    
        /**
         * Window type: special application window that is displayed while the
         * application is starting.  Not for use by applications themselves;
         * this is used by the system to display something until the
         * application can show its own windows.
         */
        public static final int TYPE_APPLICATION_STARTING = 3;
    
        /**
         * End of types of application windows.
         */
        public static final int LAST_APPLICATION_WINDOW = 99;
    
        /**
         * Start of types of sub-windows.  The {@link #token} of these windows
         * must be set to the window they are attached to.  These types of
         * windows are kept next to their attached window in Z-order, and their
         * coordinate space is relative to their attached window.
         */
        public static final int FIRST_SUB_WINDOW        = 1000;
    
        /**
         * Window type: a panel on top of an application window.  These windows
         * appear on top of their attached window.
         */
        public static final int TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW;
    
        /**
         * Window type: window for showing media (e.g. video).  These windows
         * are displayed behind their attached window.
         */
        public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;
    
        /**
         * Window type: a sub-panel on top of an application window.  These
         * windows are displayed on top their attached window and any
         * {@link #TYPE_APPLICATION_PANEL} panels.
         */
        public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2;

        /** Window type: like {@link #TYPE_APPLICATION_PANEL}, but layout
         * of the window happens as that of a top-level window, not
         * as a child of its container.
         */
        public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
        
        /**
         * Window type: window for showing overlays on top of media windows.
         * These windows are displayed between TYPE_APPLICATION_MEDIA and the
         * application window.  They should be translucent to be useful.  This
         * is a big ugly hack so:
         * @hide
         */
        public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4;
    
        /**
         * End of types of sub-windows.
         */
        public static final int LAST_SUB_WINDOW         = 1999;
        
        /**
         * Start of system-specific window types.  These are not normally
         * created by applications.
         */
        public static final int FIRST_SYSTEM_WINDOW     = 2000;
    
        /**
         * Window type: the status bar.  There can be only one status bar
         * window; it is placed at the top of the screen, and all other
         * windows are shifted down so they are below it.
         */
        public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;
    
        /**
         * Window type: the search bar.  There can be only one search bar
         * window; it is placed at the top of the screen.
         */
        public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;
    
        /**
         * Window type: phone.  These are non-application windows providing
         * user interaction with the phone (in particular incoming calls).
         * These windows are normally placed above all applications, but behind
         * the status bar.
         */
        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
    
        /**
         * Window type: system window, such as low power alert. These windows
         * are always on top of application windows.
         */
        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
        
        /**
         * Window type: keyguard window.
         */
        public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
        
        /**
         * Window type: transient notifications.
         */
        public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
        
        /**
         * Window type: system overlay windows, which need to be displayed
         * on top of everything else.  These windows must not take input
         * focus, or they will interfere with the keyguard.
         */
        public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
        
        /**
         * Window type: priority phone UI, which needs to be displayed even if
         * the keyguard is active.  These windows must not take input
         * focus, or they will interfere with the keyguard.
         */
        public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
        
        /**
         * Window type: panel that slides out from the status bar
         */
        public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8;
    
        /**
         * Window type: dialogs that the keyguard shows
         */
        public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9;
        
        /**
         * Window type: internal system error windows, appear on top of
         * everything they can.
         */
        public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
        
        /**
         * Window type: internal input methods windows, which appear above
         * the normal UI.  Application windows may be resized or panned to keep
         * the input focus visible while this window is displayed.
         */
        public static final int TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11;

        /**
         * Window type: internal input methods dialog windows, which appear above
         * the current input method window.
         */
        public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12;

        /**
         * Window type: wallpaper window, placed behind any window that wants
         * to sit on top of the wallpaper.
         */
        public static final int TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13;

        /**
         * Window type: panel that slides out from over the status bar
         */
        public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14;

        /**
         * Window type: secure system overlay windows, which need to be displayed
         * on top of everything else.  These windows must not take input
         * focus, or they will interfere with the keyguard.
         *
         * This is exactly like {@link #TYPE_SYSTEM_OVERLAY} except that only the
         * system itself is allowed to create these overlays.  Applications cannot
         * obtain permission to create secure system overlays.
         * @hide
         */
        public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;

        /**
         * Window type: the drag-and-drop pseudowindow.  There is only one
         * drag layer (at most), and it is placed on top of all other windows.
         * @hide
         */
        public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16;

        /**
         * Window type: panel that slides out from under the status bar
         * @hide
         */
        public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17;

        /**
         * Window type: (mouse) pointer
         * @hide
         */
        public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;

        /**
         * Window type: Navigation bar (when distinct from status bar)
         * @hide
         */
        public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;

        /**
         * Window type: The volume level overlay/dialog shown when the user
         * changes the system volume.
         * @hide
         */
        public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;

        /**
         * Window type: The boot progress dialog, goes on top of everything
         * in the world.
         * @hide
         */
        public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;

        /**
         * Window type: Fake window to consume touch events when the navigation
         * bar is hidden.
         * @hide
         */
        public static final int TYPE_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22;

        /**
         * End of types of system windows.
         */
        public static final int LAST_SYSTEM_WINDOW      = 2999;


英文注释都不难,很好理解。比较常用的,也是我们这个文章分析可能要说到的:
TYPE_BASE_APPLICATION[DecorView被添加的时候用的这种类型] 

TYPE_APPLICATION[Dialog被添加的使用用的这种类型]

TYPE_STATUS_BAR [StatusBar状态栏属于这个类型]

TYPE_SEARCH_BAR [搜索栏属于这个类型]

TYPE_PHONE [来电界面用的这个类型,需要说明的是这个类型通常位于其他APP之上但是在statusbar之下]

TYPE_SYSTEM_ALERT [低电量提示属于这个类型]

TYPE_KEYGUARD [键盘属于这个类型]

TYPE_TOAST[Toast提示属于这个类型]

TYPE_SYSTEM_DIALOG[这个类型和TYPE_STATUS_BAR_PANEL的描述差不多,英文差没区分出来]

TYPE_SYSTEM_ERROR[这个类型描述说的是系统错误对话框,我认为程序crash的对话框应该属于这个类型]

TYPE_STATUS_BAR_PANEL[这个类型和TYPE_STATUS_Dialog的描述差不多,英文差没区分出来,我觉得这个更像是状态栏下拉滑出来的面板用的类型,啊啊啊啊啊啊啊啊]

大概就说这么多,接下来作个流程梳理。

本人水平有限,或多或少都肯定存在部分不准确的地方,若有发现请指出,我好修改。

联系方式:

QQ:190951132请备注“CSDN博客建议”

email:[email protected]


随风码砖自由式方向~~

追逐雷和闪电的力量~~~~~


补充:这里看到一个更详细的属性分析,http://blog.csdn.net/wang_shaner/article/details/8596380 感谢作者!~





你可能感兴趣的:(Android)