起源:前几天一个网友问我,他有个需求在来电的时候弹窗提示信息—使用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栏列表之类的),以及一些没有实体键的手机的虚拟按键之类的。
先上几张图简单看一下...
先去吃个饭,回来继续.....
---------------------------吃完了-----------------------------继续---------------------------------
接着再介绍一些后续需要涉及到的东西: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_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 感谢作者!~