zoukankan      html  css  js  c++  java
  • Android源码剖析之Framework层进阶版(Wms窗口管理)


     本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!


    上一篇我们主要讲了Ams,篇幅有限,本篇再讲讲Wms,即WindowManagerService,管理窗口的服务。主要负责窗口的创建、删除、状态等与手机交互的事情,与Ams配合使用,在SystemServer中创建,用来保持窗口层级关系方便SurfaceFlinger绘制屏幕,和传递窗口信息给InputManager调用InputDispatcher将输入消息派发到顶层窗口。


    Activity、View与Window的区别与联系,View是最底层的显示控件,Activity包含一个DecorView+Window实现类引用PhoneWindow,而Window是一个接口-用来将手势动作转化为Activity可识别的信号。至于什么叫窗口,每个Activity就是窗口、每个Toast也是一个窗口、每个系统弹窗同样是一个窗口。再比如Windows操作系统的任务栏多窗口,比较Android系统当前应用的单窗口。而窗口由什么组成,状态和界面。哈哈,听起来是不是很简单?也就是说你所有的操作会产生一个状态,这个状态会在界面上得以体现,比如后退关闭当前页面。前言介绍有点多,接下来说重点。


    1、前面讲的界面是Surface,展示由SurfaceManager来管理,状态由WindowState来管理;布局两种层叠与平铺,Windows的平铺,Android的层叠;

    2、布局对应两种实现方式:独立进程式和库共享式。作用是用来绘制屏幕和消息处理,前者独立后者依赖。这样即使一个应用崩溃系统依然完好。

    3、应用窗口的高度=屏幕-状态栏,对比苹果的屏幕-菜单栏。

    4、关于焦点,一般情况下最前面的窗口获得焦点,二般情况下系统按键获得焦点,支持窗口切换、添加动画效果。


    跟View的操作差不多,Wms也有几个动作,assignlayer给窗口分配层值越大越靠前(动态的),performlayout根据输入法窗口、状态栏和窗口动画来计算可用的大小、placesurface像draw方法一样将窗口展示在屏幕下。


    介绍几个跟Wms关联比较紧密的类

    1、WindowManagerPolicy:接口,约束Wms能干什么。

    2、WindowManager:Activity通过它调用remove和addView,Wms通过Binder类型的ViewRoot以IPC方式传给ActivityThread(UI线程),由Handler类型的ViewRoot转成本地的一个异步调用。

    3、SurfaceManager:调动SurfaceFlinger(linux驱动)绘制屏幕,使用芯片的图形加速器引擎完成工作

    4、InputManager:获得输入消息,拥有Wms引用;执行时先执行InputMonitor,使用InputWindow保存寻找焦点所需信息

    5、WindowState:真正的窗口,记录大小、层值、动画状态;每个窗口均有一个它;WindowToken用来实现IPC交互,一个窗口只有一个,子窗口均指向它;AppWindowToken指App在Wms的token用来最终管理交互。

    6、Animation:Dim和Fade,分别是变暗和渐进动画,是窗口用的最多的效果

    7、PolicyThread:WindowManagerPolicy类型,主要Wms使用异步操作的一个工具

    8、Session:SufaceSession(用于向SurfaceFlinger添加删除窗口)的包装类,显然用来保存渲染的缓存信息,主要有uid、pid等

    9、WaterMark:作用一防篡改二加通用背景,保存在/system/etc下,格式是content%

    10、VMThread:SystemServer的异步线程

    Wms最重要的就是添加和删除窗口,还是要具体讲一下的,先讲添加窗口

    创建ViewRoot对象,调用setView方法,通过IPC执行Session中的add方法,然后addWindow;在这一步需要执行一些前置

    条件判断比如参数是否合法、窗口是否已存在、将屏幕大小给到InputManager应用输入法墙纸窗口的attr.token和type一致;再

    添加窗口相关数据,如新建WindowState(包含session、ViewRoot的W对象、隶属窗口等)加入mWindowMap、传递touch

    焦点等;最后执行后置判断将窗口状态变化反映到相关数据中,比如将焦点给予可交互的窗口、计算并重新分配层值。

    接着再讲一下删除窗口,与Windows不同,用户不能直接关闭窗口,分两种显性删除直接调用WindowManager的remove方法

    隐性删除指执行finish回调隐性删除: 先发送一个消息,通知关闭窗口,removeViewImediate负责删除activity窗口,closeAll负责

    删除Activity相关如菜单、对话框窗口,删除自身的Session;然后看是否执行一个动画、尝试把焦点转移到另一个窗口,相当于

    反向执行add过程。


    接下来讲讲窗口大小,mContainingFrame(整屏)> mContentFrame(窗口实际)> mFrame(屏幕上显示),使用

    layoutWindowLv来计算窗口大小,如果是输入法则是可用大小,否则情况有三:1、考虑状态栏2、全屏3、是否排序输入法窗体

    大小;输入法窗口仅允许被添加一次、且下面不允许有内容,调用ViewRoot.W的resize方法,一般使用下面方法,防止其获得焦点

    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

    影响窗口可视状态因素有二:1、动画,2、是否显示

    最后SurfaceFlinger对窗口进行重绘,操作Surface窗口,对视图View进行变换,而动画有两种Animation(tranlslate、scale、

    rotate、alpha)对View操作进行有限变换和Tween(距离移动)对Surface操作进行变换,主要对界面进行不间断的重绘。


    多种情况下Ams会调用Wms如增删appWindowToken、设置窗口可见、动画切换等,少数情况下Wms会调用Ams如暂停App

    切换、横竖屏切换、杀死App等。


    横竖屏切换主要由三种情况引起:1、ActivityStack执行resumeTopActivityLocked2、Wms执行window操作3、人为旋转

    设备。


    最后放出来两张图,activity启动过程和停止过程






  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/fengju/p/6174388.html
Copyright © 2011-2022 走看看