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启动过程和停止过程:
Android源码剖析之Framework层进阶版(Wms窗口管理)的更多相关文章
- Android源码剖析之Framework层基础版(窗口、linux、token、Binder)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于Framework,就是应用层底下的控制层,离应用层最近,总想找个机会,写写WindowMang ...
- Android源码剖析之Framework层实战版(Ams管理Activity启动)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 讲到实战,就不得不拿两个例子来说明,本篇想拿的是应用最广泛的两个:Ams和Wms,一个管理activ ...
- Android源码剖析之Framework层升级版(窗口、系统启动)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 看本篇文章之前,建议先查看: Android源码剖析之Framework层基础版 前面讲了frame ...
- Android源码剖析之Framwork层消息传递(Wms到View)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 前面讲过Wms.Ams与Activity的一系列交互,包括创建过程.消息传递.窗口展示等,紧接上篇介 ...
- Android源码剖析之Framwork层后记篇(硬件消息传递、apk管理、输入法框架、编译过程)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 既然写到后记篇,就代表本系列到此为止,暂时告一段落:其他一些Manager随后有时间再补,就像源码的 ...
- android 源码编译及其运行模拟器相关问题记录
最近一直在看android源码相关的文档,包括编译源码,还有framework层的代码,本人很懒,一直没有写博客,今天想自己在编译一下源码,并且运行在模拟器中. 源码的版本不同,需要的jdk可能也有所 ...
- (转)Android学习进阶路线导航线路(Android源码分享)
转载请注明出处:http://blog.csdn.net/qinjuning 前言:公司最近来了很多应届实习生,看着他们充满信心但略带稚气的脸庞上,想到了去年的自己,那是的我是不是也和 现在的他们一 ...
- Android学习进阶路线导航线路(Android源码分享)
转 ...
- android源码framework下添加新资源的方法
编译带有资源的jar包,需要更改frameworks层,方法如下: 一.增加png类型的图片资源 1.将appupdate模块所有用到的png格式图片拷贝到framework/base/core/re ...
随机推荐
- js:数据结构笔记12--排序算法(2)
高级排序算法:(处理大数据:百万以上) 希尔排序:是插入排序的优化版: 首先设置间隔数组,然后按照每个间隔,分别进行排序: 如第一个间隔为5,首先a[5]与a[0]进行插入排序;然后a[6]和a[0] ...
- iOS数组排序
[_fields sortUsingComparator:^NSComparisonResult(UITextField *obj1, UITextField *obj2) { /* NSOrdere ...
- Redis Set 命令
1.Set set是string类型的无序集合,其参考来源应该属于STL中的Set. •set元素最大可以包含(2的32次方-1)个元素. •set的是通过hash table实现的,ha ...
- SGU326 Perspective(指派问题)
题目简单吧,如果知道题目要干嘛的话. 每个比赛指定A赢或者B赢使它们赢得次数不超过1赢得次数.建立一个二分图模型,X部比赛,Y部队伍,用最大流求解,如果最后最大流等于比赛场数就有解. 然而我还是掉坑里 ...
- 各新旧版本Java及其相关文档可以从这里下载
http://www.oracle.com/technetwork/java/archive-139210.html
- 生产环境下一定要开启mysqlbinlog
在没有备份数据库的情况下,可以用binlog进行恢复 在生产环境下安全第一,损失一点点效率换来的安全还是值得的. http://www.cnblogs.com/zc22/archive/2013/06 ...
- (转载)c# winform 用子窗体刷新父窗体,子窗体改变父窗体控件的值
第一种方法: 用委托,Form2和Form3是同一组 Form2 C#代码 using System; using System.Collections.Generic; using System.C ...
- 关于ztree异步加载的问题(二)
本来以为这个异步加载会很难控制,因为考虑到ztree节点图标的控制,结果并不是那么困难,ztree自己控制图标,你只要在json中设置isParent:true,它自己会识别父节点并控制图标,以下是核 ...
- 【C语言】15-预处理指令1-宏定义
预处理指令简介 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 2 ...
- C++ 'dynamic_cast' and Java 'instanceof' 使用对比
在Java中,如果A是基类,B是A的派生类,那么instanceof可以用来判断一个实例对象是A还是B,相当于一个二元操作符,但与==, >, < 不同的是,它是由字母组成,是Java的保 ...