Framework——WMS之WindowManager(窗口管理服务)实战
1、简介
WindowManager(窗口管理服务), 它是显示View的最底层,Toast,Activity,Dialog的底层都用到了这个WindowManager, 他是全局的!该类的核心无非:调用addView,removeView,updateViewLayout这几个方法 来显示View以及通过WindowManager.LayoutParams这个API来设置相关的属性。
Android为我们提供的用于与窗口管理器进行交互的一个API。我们都知道App的界面都是 由一个个的Acitivty组成,而Activity又由View组成,当我们想显示一个界面的时候, 第一时间想起的是:Activity,又或者是Dialog和Toast。 但是有些情况下,前面这三者可能满足不了我们的需求,比如我们仅仅是一个简单的显示 用Activity显得有点多余了,而Dialog又需要Context对象,Toast又不可以点击 。对于以上的情况我们可以利用WindowManager添加View到屏幕上, 或者从屏幕上移除View。他就是管理Android窗口机制的一个接口,显示View的最底层。
2、WMS功能介绍
要想了解WindowManager管理机制,首先我们先介绍WMS是一个非常重要的系统服务。
它支撑着视图相关的各项业务,这非常符合软件设计的单一职责原则,其业务和ActivityManagerService(简称AMS)一起几乎占据了framework业务的半壁江山,可见其重要性。关于WMS的内容实在太多了,这里只简单介绍其大致功能以及启动流程。
WMS的大概功能如下图所示:
image.png
这里先简单描述一下各项功能:
- 窗口管理:WMS是窗口管理者,结合WindowManager实现窗口的启动、添加、删除,以及管理窗口的大小、层级等。
- 窗口动画:在窗口切换时,使用窗口动画可以使这个过程看起来更炫更生动,这个窗口动画就是由WMS的动画子系统来负责的,动画子系统的管理者便是WindowAnimator。
- 输入系统的中转站: 触摸设备屏幕上的窗口时会产生触摸事件,InputManagerService(IMS)会对触摸事件进行处理,找到最合适的窗口来反馈事件。而WMS是这些窗口的管理者,那自然而然就成为了输入系统的中转站了。
- Surface管理:窗口并不具备绘制功能,所以每个窗口都需要一个Surface来供自己绘制,WMS就是这个Surface的管理者。
WindowManager 实现悬浮窗 详解
关于
SYSTEM_ALERT_WINDOW
权限申明直接报错
// 设置window type
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWinParams.type = WindowManager.LayoutParams.TYPE_TOAST;
} else {
mWinParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
//原因1:type为"TYPE_TOAST"在sdk19之前不接收事件,之后可以.
//原因12:type为"TYPE_PHONE"需要"SYSTEM_ALERT_WINDOW"权限.在sdk19之前不可以直接申明使用,之后不能直接申明使用.
三:用到的技术知识点:
1. OnTouch()的事件处理
2. WindowManager类及其LayoutParams的常见属性的理解
3. Handler更新UI
4. 定时器(Timer + TimerTask)
1. OnTouch事件处理
这个网上的资料很多,这里说一些注意点:
1.获取坐标
-
event.getRawX()
:获取相对屏幕的坐标X(获取Y的坐标同理) -
event.getX()
:获取相对于容器的坐标X(获取Y的坐标同理)
2.返回值
-
return true
:表示事件不往下传递了 -
return false
:表示继续传递事件
2. WindowManager类
获取方式:
mWmManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams类
this.mWinParams = new WindowManager.LayoutParams();
// 设置图片格式,效果为背景透明
mWinParams.format = PixelFormat.RGBA_8888;
// 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)
mWinParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
// 参考系为左上
mWinParams.gravity= Gravity.LEFT | Gravity.TOP;
mScreenHeight = mWmManager.getDefaultDisplay().getHeight();
// 以屏幕左上角为原点,设置x、y初始值,相对于gravity
mWinParams.x = mScreenWidth/4;
mWinParams.y = mScreenHeight/4;
// 设置悬浮窗口长宽数据
mWinParams.width = FrameLayout.LayoutParams.WRAP_CONTENT;
mWinParams.height = FrameLayout.LayoutParams.WRAP_CONTENT;
其中需要注意的是其Gravity
属性:
注意:Gravity不是说你添加到WindowManager中的View相对屏幕的几种放置,而是说你可以设置你的 参 考 系 !
例如:mWinParams.gravity= Gravity.LEFT | Gravity.TOP;
意思是以屏幕左上角为参考系,那么屏幕左上角的坐标就是(0,0),这是你后面摆放View位置的唯一依据.当你设置为mWinParams.gravity = Gravity.CENTER;
那么你的屏幕中心为参考系,坐标(0,0).一般我们用屏幕左上角为参考系.
设置WindowManager中的View的透明度
使用:LayoutParams.alpha
属性(0.0f ~ 1.0f),1.0f不透明,0.0f全透明,源码如下:
/**
* An alpha value to apply to this entire window.
* An alpha of 1.0 means fully opaque and 0.0 means fully transparent
*/
public float alpha = 1.0f;
Handler更新UI(略)
定时器
TimerTask timerTask = new TimerTask(){其实就是一个Runnable};
看他的类:
public abstract class TimerTask implements Runnable{...}
Timer mtimer=new Timer();
使用的时候:
mtimer.schedule(timerTask,0,3);//参数1:执行的任务;参数2:延迟0毫米执行;参数3:每隔3毫秒执行一次任务;
要实现WindowManager添加的窗口,实现动画显示,就需要添加如下红色的属性,其他的添加View只要设置其Animations属性也会实现动画,当然自己实现也可,但是能直接用系统的已经实现好的,也很方便。
windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
WindowParams = new LayoutParams(LayoutParams.FLAG_FULLSCREEN,LayoutParams.FLAG_FULLSCREEN);
WindowParams.type=LayoutParams.TYPE_SYSTEM_ERROR;
WindowParams.flags=LayoutParams.FLAG_ALT_FOCUSABLE_IM; //window gets focus
WindowParams.format=PixelFormat.TRANSPARENT; //set the opacity to 100%
WindowParams.windowAnimations=android.R.style.Animation_Translucent; // set the animation for the window
WindowParams.gravity = Gravity.RIGHT | Gravity.TOP;
windowManager.addView(view, WindowParams);
展示:
![](https://img.haomeiwen.com/i28055132/528ff6d0307f5d4b.gif)
【戳我获取】《Framework精通手册》
![](https://img.haomeiwen.com/i28055132/f99d37c89166c8eb.png)
![](https://img.haomeiwen.com/i28055132/9456212749f2ed21.png)
![](https://img.haomeiwen.com/i28055132/2f1068e171d79101.png)
【一键获取】Frame Work源码解析手册
文末
本文简单实现一个悬浮窗;framework之wms机制中的WindowManager(窗口管理服务)得简单使用。总上面可以领取framework学习资料,自己整理出的很全的核心技术点。点击可免费获取。
网友评论