起源:前幾天一個網友問我,他有個需求在來電的時候彈窗提示信息—使用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是屬於什麼類型的窗口(關於窗口,後續內容會依次提到相關知識)。
<span style="white-space:pre"> </span>public int type;
<span style="white-space:pre"> </span>/**
* 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, <em>not</em>
* 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 感謝作者!~