Window与WMS通信过程

简介: Window与WMS通信过程

Window与WMS通信过程


我的简书同步发布:Window与WMS通信过程

转载请注明出处:【huachao1001的专栏:http://blog.csdn.net/huachao1001

上一篇文章【理清Activity、View及Window之间关系】我们大致知道了Window的绘制过程,但是比较笼统,本文主要介绍Window对象与(后面缩写为WMS)之间是如何通信。毫无疑问,肯定是通过IPC(Binder机制),这点肯定都知道,但是我们要学习是的是,哪些类参与了IPC调用过程。另外,本文没有研究源码,而是通过阅读其他研究源码的文章,然后总结出来,以更容易理解的方式展示。本文设计到的相关资料在文章最后一一列出。


1 Window添加的大致过程

Window的添加过程需要通过WindowManager的addView来实现,WindowManager是一个接口,真正的实现是WindowManagerImpl。而WindowManagerImpl全部是转移给WindowManagerGlobal来处理,WindowManagerImpl这种工作模式是典型的桥接模式。WindowManagerImpl内三大操作过程如下:

public void addView(View view,ViewGroup.LayoutParams params){
    mGlobal.addView(view,params,mDisplay,mParantWindow);
}
public void updateViewLayout(View view,ViewGroup.LayoutParams params){
    mGlobal.updateViewLayout(view,params);
}
public void removeView(View view){
    mGlobal.removeView(view,false);
}

从WindowManagerGlobal名称可以看出,它是一个全局的WindowManager,其内部维护如下几个列表:

private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>()
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.layoutParams>();
private final ArraySet<View> mDyingViews = new ArraySet<View>();

其中:

mViews:存储所有Window所对应的View

mRoots:存储的是所有Window所对应的ViewRootImpl

mParams:存储的是所有Window所对应的布局参数

mDyingView:存储了那些正在被删除的View对象,或者说是那些已经调用了removeView方法但是删除操作还未完成的Window对象。

addView中通过如下方式将Window的一系列对象添加到列表中:

root=new ViewRootImpl(view.getContext(),display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);

可以看到,到目前为止,只是把相应的对象存放到ArrayList列表中。后面还需要将View给显示出来。绘制View需要通过ViewRootImpl的setView方法来实现。在setView内部是通过requestLayout来完成一部刷新请求的。

public void requestLayout(){
    if(!mHandlingLayoutInlayoutRequest){
        checkThread();
        mLayoutRequested=true;
        scheduleTraversals();
    }
}

其中scheduleTraversals是View绘制的入口!


下面我们看看ViewRootImpl是内部机制。


2 ViewRootImpl内部机制

ViewRootImpl用于管理窗口的根View,并和WMS进行交互。ViewRootImpl中有一个内部类: W,以及另一个内部类:ViewRootHandler。


W继承自IWindow.Stub。是一个Binder对象,用于接收WMS的各种消息, 如按键消息, 触摸消息等。


ViewRootHandler,是Handler的子类, W会通过Looper把消息传递给ViewRootHandler。


ViewRootImpl有一个W类型的成员mWindow,ViewRootImpl在构造函数中创建一个W的实例并赋值给mWindow。


在ViewRootImpl的setView方法(此方法运行在UI线程)中,会通过IPC的方式跨进程向WMS发起一个远程调用,从而将DecorView最终添加到Window上,在这个过程中,ViewRootImpl、DecorView和WMS会彼此向关联.


另外,WMS有时也需要向ViewRootImpl发送远程请求,比如,点击事件是由用户的触摸行为所产生的,因此它必须要通过硬件来捕获,跟硬件之间的交互自然是Android系统自己把握,Android系统将点击事件交给WMS来处理。WMS通过远程调用将事件发送给ViewRootImpl,在ViewRootImpl中,有一个方法,叫做dispatchInputEvent,最终将事件传递给DecorView。


3 Window与WMS之间的双向通信

接下来,由WindowSession来完成最后的Window添加过程。mWindowSession本身是一个IWindowSession类型对象,通过内部代理类Proxy访问远程Session类(Binder机制) 。在Session内部通过WMS来实现Window的添加。如此一来Window的添加请求就交给了WMS去处理了,如下图所示:

image.png

WindowManagerService内部为每个应用保留一个单独的Session,如下图所示:

image.png

前面我们说过,每个Window对应一个ViewRootImpl及一个View Tree。也就是说,每个Activity对应的Window(一个或多个)内通过其内置的ViewRootImpl完成向WMS的请求过程。


一个应用中的所有Activity共用一个Session,一个Window在WMS内部对应一个WindowState,WindowState维护窗口的状态以及根据适当的机制来调整窗口的状态。


如果一个Activity多个Window,如对话框、Popup类型、或者通过ViewManager将View直接加入WMS,等等。在这些情况下,一个Activity就会创建多个Window,相应的WMS中也会对应多个WindowState,如下图所示:

image.png


4 WMS控制窗口的显示

以下内容来自老罗的的博客,后面附有资料链接。


WMS服务大致按照以下方式来控制哪些窗口需要显示的以及要显在哪里:


每一个Activity窗口的大小都等于屏幕的大小,因此,只要对每一个Activity窗口设置一个不同的Z轴位置,然后就可以使得位于最上面的,即当前被激活的Activity窗口,才是可见的。


每一个子窗口的Z轴位置都比它的父窗口大,但是大小要比父窗口小,这时候Activity窗口及其所弹出的子窗口都可以同时显示出来。


对于非全屏Activity窗口来说,它会在屏幕的上方留出一块区域,用来显示状态栏。这块留出来的区域称对于屏幕来说,称为装饰区(decoration),而对于Activity窗口来说,称为内容边衬区(Content Inset)。


输入法窗口只有在需要的时候才会出现,它同样是出现在屏幕的装饰区或者说Activity窗口的内容边衬区的。


对于壁纸窗口,它出现需要壁纸的Activity窗口的下方,这时候要求Activity窗口是半透明的,这样就可以将它后面的壁纸窗口一同显示出来。


两个Activity窗口在切换过程,实际上就是前一个窗口显示退出动画而后一个窗口显示开始动画的过程,而在动画的显示过程,窗口的大小会有一个变化的过程,这样就导致前后两个Activity窗口的大小不再都等于屏幕的大小,因而它们就有可能同时都处于可见的状态。事实上,Activity窗口的切换过程是相当复杂的,因为即将要显示的Activity窗口可能还会被设置一个启动窗口(Starting Window)。一个被设置了启动窗口的Activity窗口要等到它的启动窗口显示了之后才可以显示出来。


参考资料:

1. 【Android窗口管理服务WindowManagerService的简要介绍和学习计划 】

2. 《Android开发艺术探索》

3. 【Android 应用程序建立与WMS服务之间的通信过程】

4. 【Android Window Manager Subsystem Research 】

相关文章
|
算法 Shell 开发者
【Conan 入门教程 】Conan 2.1中的打印方式/输出管理
【Conan 入门教程 】Conan 2.1中的打印方式/输出管理
299 1
|
Web App开发 缓存 数据库
DMS产品常见问题之DMS数据规定失败如何解决
DMS(数据管理服务,Data Management Service)是阿里云提供的一种数据库管理和维护工具,它支持数据的查询、编辑、分析及安全管控;本汇总集中了DMS产品在实际使用中用户常遇到的问题及其相应的解答,目的是为使用者提供快速参考,帮助他们有效地解决在数据管理过程中所面临的挑战。
|
算法 物联网 定位技术
基于WIFI指纹的室内定位算法matlab仿真
基于WIFI指纹的室内定位算法matlab仿真
|
机器学习/深度学习 运维 监控
提升数据中心效率的关键策略
【2月更文挑战第31天】随着数据量的爆炸性增长,数据中心作为信息处理和存储的核心设施,其运行效率直接影响到企业的服务质量和成本控制。本文将深入探讨数据中心效率提升的关键技术和管理策略,包括能效优化、自动化运维、以及弹性资源配置等。通过分析当前的挑战和解决方案,我们旨在为数据中心管理者提供实用的参考和指导,帮助他们在确保系统稳定性的同时,有效降低能耗和运营成本。
|
消息中间件 Linux 网络安全
Linux下源码安装RabbitMQ并设置服务开机启动
Linux下源码安装RabbitMQ并设置服务开机启动
578 0
|
5月前
|
存储 人工智能 数据可视化
企业级 AI 模型无代码落地指南:基于阿里云工具链,从 0 到 1 实现业务价值
某汽车零部件厂商通过阿里云PAI、OSS等工具,实现无代码AI质检落地:仅用控制台操作完成数据治理到部署,质检效率提升3倍,模型周期从2月缩至2周。本文详解全栈可视化方案,助力企业零代码落地AI。
628 1
|
机器学习/深度学习 人工智能 算法
小白教程-阿里云快速搭建Stable-Diffusion WebUI环境+免费试用
Stable-Diffusion 是目前热门的AIGC图像生成方案,通过开源与社区共享模型的方式,成为AI艺术与创意产业的重要工具。本文介绍通过阿里云快速搭建SD WebUI的服务,并有免费试用权益,适合新手入门。通过详细步骤指导,帮助读者轻松上手,享受创作乐趣。
2785 0
|
机器学习/深度学习 传感器 算法
改进黑猩猩优化算法SLWCHOA 可直接运行 提供23个基准函数对比与秩和检验 注释详细适合新手小白~Matlab
改进黑猩猩优化算法SLWCHOA 可直接运行 提供23个基准函数对比与秩和检验 注释详细适合新手小白~Matlab
|
前端开发 测试技术 数据库
使用Ruby on Rails进行快速Web开发的技术探索
【8月更文挑战第12天】Ruby on Rails以其高效、灵活和易于维护的特点,成为了快速Web开发领域的佼佼者。通过遵循Rails的约定和最佳实践,开发者可以更加专注于业务逻辑的实现,快速构建出高质量的Web应用。当然,正如任何技术框架一样,Rails也有其适用场景和局限性,开发者需要根据项目需求和个人偏好做出合适的选择。
|
数据采集 前端开发 测试技术
Selenium中定位元素的9种方法
在Selenium中,定位页面元素是自动化测试和网页爬虫的基础。常用的9种元素定位方法包括:ID、Name、Class Name、Tag Name、CSS Selector、XPath、Link Text、Partial Link Text,以及XPath和CSS选择器的组合使用。每种方法各有优劣,建议根据页面的具体情况和元素的属性选择最合适的方法,并使用显式等待确保元素可用。
2024 5

热门文章

最新文章