WindowManager和WindowManagerService的简单接触
学了一下悬浮窗的创建,随手翻阅了一些关于window类,windowmanager以及WindowManagerService的博客,也参考了《Android内核剖析》和《Android开发艺术探索》之后对此也有了一些认识,简单的记录一下。
WindowManager用来访问Window类的入口。 WindowManagerService 是 Android中图形用户接口的引擎,主要负责管理所有窗口(添加,更新,删除)。也就是说Android系统要想创建一个窗口都必须经由windowManagerService的批准。
《Android开发艺术探索》需要简单的描述一下:
WindowManager是一个接口,真正实现类似WindowManagerImpl类。
wManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);的强制转换可以看出。
所以windowManager.addView( )和updateViewLayout( )以及removeView( )也是由WindowManagerImpl来完成的,有意思的是他也委托WindowManagerGlobal类来完成最后的处理。(一个比一个懒,开玩笑)。这里用到了WindowManagerImpl的桥接模式。最终会调用RootView.addView(),对应下文窗口创建的第2步。
看一下WindowManager实现添加view的代码:
private static WindowManager wManager;
private static FloatSmallLayout smallLayout;
private static WindowManager.LayoutParams smallParams;
private static WindowManager.LayoutParams bigParams;
private static FloatBigLayout bigLayout;
private static float screenHeight;
private static float screenWidth;
public static void createFlaotView(Context context) {
wManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
screenHeight = wManager.getDefaultDisplay().getHeight();
screenWidth = wManager.getDefaultDisplay().getWidth();
if (smallLayout == null) {
smallLayout = new FloatSmallLayout(context);
if (smallParams == null) {
smallParams = new WindowManager.LayoutParams();
//这里的参数可以参考网上的文章具体含义
smallParams.type = WindowManager.LayoutParams.TYPE_PHONE;
smallParams.format = PixelFormat.RGBA_8888;
smallParams.gravity = Gravity.LEFT | Gravity.TOP;
smallParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
//设置悬浮窗的位置
smallParams.y = (int) (screenHeight / 2);
smallParams.x = (int) (screenWidth / 2);
//悬浮窗的width 和 height(等号后边可以赋你想要的值)
smallParams.width = smallLayout.viewWidth;
smallParams.height = smallLayout.viewHeight;
wManager.addView(smallLayout, smallParams);
}
}
}
个人认为《Android内核剖析》的有三个概念必须要说一下,可能很多事情能会明朗。
窗口:一个独立的界面,如activity交互界面,对话框等。
window:他是一个类,由PhoneWindow类实现,其中Activity类实现了Window.Callback接口而具有通用操作的窗口。
view:经常用到,一个能够独立交互的元素,如textview,button等。
Wms中窗口中两个组成部分:
- WindowState类:描述窗口比如窗口的大小以,层值以及窗口动画过程等信息。
- surface:屏幕对应的界面。
三种常见操作:
- assign layer:为窗口分配层值
- perform layout:计算窗口的大小
- place surface:调整surface对象的属性,并重新显示到屏幕。每一个窗口都对应一个windowstate类,在assign layer 和perfor layout的过程产生的结果影响windowstate的参数值,在place surface中将windowstate的值赋给Surface对象,并告知Surface Flinger服务重新显示这些Surface对象。
窗口管理的策略机制
- 虽然WindowManagerService可以随意的添加和删除窗口,但是某些情况下要遵循一定的条件约束,而这个条件可以称之为策略机制,这种描述相对容易理解,可能不太严谨。比如只能有一个系统状态栏和一个导航栏。
wms中表示窗口的类
WindowState:在上边介绍过,每个窗口都有一个windowstate对象
WindowToken:每个窗口都会对应一个windowToken对象,但是一个窗口的所有子窗口对应同一个WindowToken
AppWindowToken:如果该窗口是一个activity窗口,则该窗口对应一个A品牌WindowToken对象
窗口的创建
窗口的创建分为主动调用和间接调用。直接用WindowManager.addView( )这是主动有程序员自己调用的。再者启动activity或者对话框时系统的间接调用。前文所说,窗口的创建一定会经由WMS的,而主动调用和间接调用两者也都会经历某一相同的过程,即WindowManager.addView( );
以下的阐述均是在WindowManager.addView( )之后的操作
1.wm.addView();
2.创建ViewRoot对象
3.ViweRoot.setView();
4.通过IPC方式调用 WMS中Session类的add();
5.在add中间接调用WMS.addWindow();
以下分析addWindow(),主要做三件事情
1)进行前置处理,判断参数是否合法
2)具体添加和窗口相关的数据
3)后置处理,即添加窗口引起的状态变化