1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android 浮窗示例代码 Android 浮窗开发之窗口层级(示例代码)

android 浮窗示例代码 Android 浮窗开发之窗口层级(示例代码)

时间:2020-04-06 11:03:34

相关推荐

android 浮窗示例代码 Android 浮窗开发之窗口层级(示例代码)

很多人都知道如何去实现一个简单的浮窗,但是却很少有人去深入的研究背后的流程机制,由于项目中浮窗交互比较复杂,遇到了些坑查看了很多资料,故总结浮窗涉及到的知识点:

窗口层级关系(浮窗是如何“浮”的)?

浮窗有哪些限制,如何越过用户授权实现浮窗功能?

窗口与用户输入系统(Activity是如何接收到touch事件?)。

本章我们来研究第一个问题:浮窗为何会浮。 浮窗之所以叫浮窗,是因为它能悬浮于应用或者桌面窗口之上,能脱离Activity而存在。为了研究其中区别,我们先来看看我们最熟悉的Activity是怎么显示出来的。

Activity是怎么显示出来的?

要弄清这个问题答案,我们先从Activity的setContentView()这个方法的源码开始找起,在Activity中看到setCententView的源码:

public void setContentView(int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

getWindow是返回返回Activity的mWindow变量,指向一个Window的对象,Window是一个抽象类,这里返回的是PhoneWindow对象(PhoneWindow是Window的子类),PhoneWindow中有一个DecorView对象,decorView成员,这是一个FrameLayout,setContentView的子布局最终会添加到decorView中,这个decorView就是当前窗口的根视图,这个根视图是如何最终被绘制出来的?在ActivityThread中有这样一段代码:

l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

l.softInputMode |= forwardBit;

if (a.mVisibleFromClient) {

a.mWindowAdded = true;

wm.addView(decor, l);

}

这个decorView,最终会被WindowManager.addView添加到绘制系统中,并类型是WindowManager.LayoutParams.TYPE_BASE_APPLICATION,这个参数决定了要绘制的窗口的z轴层次,为了避免思维栈过深,这里就不贴出详细的源码跟踪过程了,直接给结论。

先来看看Activity和window的关系:

再来window和View的关系:

Activity窗口显示过程:

说Activity是怎么显示出来的,其实是说Activity管理的View是怎么显示出来的。最后再来总结一下:

一、Activity通过setContentView设置的视图是添加到PhoneWindow的根视图decor中。

二、Window是一个抽象的概念,Window关了了一个View(根视图),最终被WindowManager管理的还是一个View(根视图)和它的LayoutParams,视图绘制刷新都是通过WindowManager(WindowManagerGlobal)与WindowManagerServiceIPC交互调用底层绘制的。

三、Activity是四大组件中唯一和窗体紧密联系的组件(这是为什么会有初学者把Activity直接理解为绘制界面的原因),所有掌管的视图只不过是一种window和Dialog、Toast、墙纸所掌管的Window类型不一样。

浮窗为什么会“浮”?

上面讲到Activity的显示过程其实已经揭示了通用界面的显示过程,浮窗的显示过程更为简单:

做过浮窗的同学应该都明白了,为啥浮窗能脱离Activity而显示,本质上我们是把一个View交给WindowManager来管理了,LayoutParams.type类型决定了这个View显示窗口的类型,不同类型显示的窗口层次(z轴)是不一样的。大方面来讲可以分为应用窗口(APPLICATION_WINDOW)、子窗口(SUB_WINDOW)、系统窗口(SYSTEM_WINDOW)三种类型,应用窗口z轴范围是1~99,子窗口的范围是1001~1999,系统窗口是(2000~2999),所以要实现浮动窗口我们只能在系统窗口范围中实现。

类型

常量范围

子类

常量值

说明

例子

APPLICATION_WINDOW

1~99

TYPE_BASE_APPLICATION

1

TYPE_APPLICATION

2

应用窗口

大部分的应用程序窗口

TYPE_APPLICATION_STARTING

3

应用程序的Activity显示之前由系统显示的窗口

LAST_APPLICATION_WINDOW

99

SUB_WINDOW

1000~1999

FIRST_SUB_WINDOW

1000

TYPE_APPLICATION_PANEL

1000

显示在母窗口之上,遮挡其下面的应用窗口。

TYPE_APPLICATION_MEDIA

1001

显示在母窗口之下,如果应用窗口不挖洞,即不可见。

SurfaceView,在小窗口显示时设为MEDIA, 全屏显示时设为PANEL

TYPE_APPLICATION_SUB_PANEL

1002

TYPE_APPLICATION_ATTACHED_DIALOG

1003

TYPE_APPLICATION_MEIDA_OVERLAY

1004

用于两个SurfaceView的合成,如果设为MEDIA,则上面的SurfaceView 挡住下面的SurfaceView

SYSTEM_WINDOW

2000~2999

TYPE_STATUS_BAR

2000

顶部的状态栏

TYPE_SEARCH_BAR

2001

搜索窗口,系统中只能有一个搜索窗口

TYPE_PHONE

2002

电话窗口

TYPE_SYSTEM_ALERT

警告窗口,在所有其他窗口之上显示

电量不足提醒窗口

TYPE_KEYGUARD

锁屏界面

TYPE_TOAST

短时的文字提醒小窗口

TYPE_SYSTEM_OVERLAY

没有焦点的浮动窗口

TYPE_PRIORITY_PHONE

紧急电话窗口,可以显示在屏保之上

TYPE_SYSTEM_DIALOG

系统信息弹出窗口

比如SIM插上后弹出的运营商信息窗口

TYPE_KEYGUARD_DIALOG

跟KeyGuard绑定的弹出对话框

锁屏时的滑动解锁窗口

TYPE_SYSTEM_ERROR

系统错误提示窗口

ANR 窗口

TYPE_INPUT_METHOD

输入法窗口,会挤占当前应用的空间

TYPE_INPUT_METHOD_DIALOG

弹出的输入法窗口,不会挤占当前应用窗口空间,在其之上显示

TYPE_WALLPAPER

墙纸

TYPE_STATUS_BAR_PANEL

从状态条下拉的窗口

TYPE_SECURE_SYSTEM_OVERLAY

只有系统用户可以创建的OVERLAY窗口

TYPE_DRAG

浮动的可拖动窗口

360安全卫士的浮动精灵

TYPE_STATUS_BAR_PANEL

TYPE_POINTER

光标

TYPE_NAVIGATION_BAR

TYPE_VOLUME_OVERLAY

音量调节窗口

TYPE_BOOT_PROGRESS

启动进度,在所有窗口之上

TYPE_HIDDEN_NAV_CONSUMER

隐藏的导航栏

TYPE_DREAM

屏保动画

TYPE_NAVIGATION_BAR_PANEL

2024

Navigation bar 弹出的窗口

比如说应用收集栏

TYPE_UNIVERSAL_BACKGROUND

2025

TYPE_DISPLAY_OVERLAY

2026

用于模拟第二显示设备

TYPE_MAGNIFICATION

2027

用于放大局部

TYPE_RECENTS_OVERLAY

2028

当前应用窗口,多用户情况下只显示在用户节目

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。