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

  • 窗口层级关系(浮窗是如何“浮”的)?
  • 浮窗有哪些限制,如何越过用户授权实现浮窗功能?
  • 窗口与用户输入系统(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 2003 警告窗口,在所有其他窗口之上显示 电量不足提醒窗口
    TYPE_KEYGUARD 2004 锁屏界面  
    TYPE_TOAST 2005 短时的文字提醒小窗口  
    TYPE_SYSTEM_OVERLAY 2006 没有焦点的浮动窗口  
    TYPE_PRIORITY_PHONE 2007 紧急电话窗口,可以显示在屏保之上  
    TYPE_SYSTEM_DIALOG 2008 系统信息弹出窗口 比如SIM插上后弹出的运营商信息窗口
    TYPE_KEYGUARD_DIALOG 2009 跟KeyGuard绑定的弹出对话框 锁屏时的滑动解锁窗口
    TYPE_SYSTEM_ERROR 2010 系统错误提示窗口 ANR 窗口
    TYPE_INPUT_METHOD 2011 输入法窗口,会挤占当前应用的空间  
    TYPE_INPUT_METHOD_DIALOG 2012 弹出的输入法窗口,不会挤占当前应用窗口空间,在其之上显示  
    TYPE_WALLPAPER 2013 墙纸  
    TYPE_STATUS_BAR_PANEL 2014 从状态条下拉的窗口  
    TYPE_SECURE_SYSTEM_OVERLAY 2015 只有系统用户可以创建的OVERLAY窗口  
    TYPE_DRAG 2016 浮动的可拖动窗口 360安全卫士的浮动精灵
    TYPE_STATUS_BAR_PANEL 2017    
    TYPE_POINTER 2018 光标  
    TYPE_NAVIGATION_BAR 2019    
    TYPE_VOLUME_OVERLAY 2020 音量调节窗口  
    TYPE_BOOT_PROGRESS 2021 启动进度,在所有窗口之上  
    TYPE_HIDDEN_NAV_CONSUMER 2022 隐藏的导航栏  
    TYPE_DREAM 2023 屏保动画  
    TYPE_NAVIGATION_BAR_PANEL 2024 Navigation bar 弹出的窗口 比如说应用收集栏
    TYPE_UNIVERSAL_BACKGROUND 2025    
    TYPE_DISPLAY_OVERLAY 2026 用于模拟第二显示设备  
    TYPE_MAGNIFICATION 2027 用于放大局部  
    TYPE_RECENTS_OVERLAY 2028 当前应用窗口,多用户情况下只显示在用户节目

转载于:https://www.cnblogs.com/lianghe01/p/6259772.html

Android 浮窗开发之窗口层级相关推荐

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

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

  2. android 更改窗口的层次,浮窗开发之窗口层级

    最近在项目中遇到了这样的需求:需要在特定的其他应用之上悬浮自己的UI交互(拖动.输入等复杂的UI交互),和九游的浮窗类似,不过我们的比九游的体验更好,我们越过了很多授权的限制. 浮窗效果 很多人都知道 ...

  3. Android浮窗权限判断

    在开启浮窗前,要判断一下,是否能够得到浮窗权限打开浮窗. 在方法中添加以下代码: //悬浮窗权限判断if (Settings.canDrawOverlays(MainActivity.this)) { ...

  4. Android浮窗实现(WindowManager)

    浮窗就是当当前页面关闭后,仍能在手机上显示的窗口,像浮在最上层一样,一直存在,一般可跟随手拖动而移动. 加速球就是一个浮窗. 浮窗的大小和形状等都可以自己设定,不是一定的. 效果(屏幕中小方形为浮窗, ...

  5. android浮窗播放器,Android仿优酷视频的悬浮窗播放效果

    之前接了需求要让视频播放时可以像优酷视频那样在悬浮窗里播放,并且悬浮窗和主播放页面之间要实现无缝切换,项目中使用的是自封装的ijkplayer 这个要求就代表不能在悬浮窗中新建视频控件,所以需要在悬浮 ...

  6. Android悬浮窗使用及窗口设置相关

    显示一个悬浮窗,窗口类型设置,获取状态栏高度 1.显示一个悬浮窗 首先通过 getSystemService(Context.WINDOW_SERVICE) 拿到 WindowManager , 然后 ...

  7. Android浮窗权限研究(转载)

    这篇博客主要介绍的是 Android 主流各种机型和各种版本的悬浮窗权限适配,但是由于碎片化的问题,所以在适配方面也无法做到完全的主流机型适配,这个需要大家的一起努力,这个博客的名字永远都是一个将来时 ...

  8. python 悬浮窗_python浮窗

    import wx; app = wx.App(); win = wx.Frame(None,title="老穆视频",pos=(900,20),size=(300,60),sty ...

  9. Android中浮窗的开发详述

    1. 简单概述一下开发浮窗的步骤 (1)创建一个服务,在服务中可以创建一个Handler接收Activity发过来的命令,在服务中创建浮窗和移除浮窗: (2)在Activty中绑定服务,并可通过Mes ...

最新文章

  1. 如何在Bash脚本中将DOS / Windows换行符(CRLF)转换为Unix换行符(LF)?
  2. 德州学院计算机吴,计算机与信息学院举办“博士讲堂”系列讲座
  3. const debug = require(‘debug‘)(‘cnpm‘)
  4. 基于Go实现的秒杀系统
  5. linux禁用及启用pcie设备,KVM 介绍(4):I/O设备直接分配和 SRIOV [KVM PCI/PCIe PassThrough SRIOV]...
  6. link标签的几个用法,帮助提高页面性能
  7. 关于python全局变量
  8. 结构体的成员偏移地址和字节对齐
  9. 【python】面向对象编程
  10. CF914D Bash and a Tough Math Puzzle
  11. 【Verilog】移位寄存器总结:移位寄存器、算数移位寄存器、线性反馈移位寄存器(LFSR)
  12. Solaris11操作命令汇总
  13. gd动态曲线 php_php顶用GD绘制折线图
  14. 《opencv学习笔记》-- 感兴趣区域(ROI)、图像混合
  15. 【前端实例代码】用HTML、CSS和JavaScript创建一个简易图片编辑器(实现图片的亮度、饱和度、灰度、颜色反转、图片旋转镜面翻转等滤镜效果)
  16. Qt之热敏打印机设置
  17. 2019瓜子网后台开发笔试题目
  18. 某在线商店电子产品销售数据分析-RFM分析方法
  19. 【PDN仿真笔记7-使用Sigrity PowerSI进行PDN仿真的方法2】
  20. 计算机趣味数学社团活动管理制度,小学趣味数学社团活动管理制度

热门文章

  1. C++中static与const成员
  2. 动态规划算法 - 钢条切割问题
  3. Android RecyclerView 列表加载图片宽高适配
  4. Android基础 获取屏幕的宽与高
  5. java基础—线程间的通讯 生产者与消费者
  6. volatile学习
  7. Tennis Game CodeForces - 496D(唯一分解定理,费马大定理)
  8. 回忆Java基础中Map的遍历方法
  9. 2、SQL UNION 和 UNION ALL 操作符
  10. 团队冲刺第一阶段第三天