WindowManager和WindowManagerService的简单接触

和自甴很熟 提交于 2019-11-29 18:30:23

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)后置处理,即添加窗口引起的状态变化
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!