Android进阶——WMS与AMS浅析

Posted Yawn,

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android进阶——WMS与AMS浅析相关的知识,希望对你有一定的参考价值。

1.简介

可以毫不夸张的说,android的framework层主要是由WMS、AMS还有View所构成,这三个模块穿插交互在整个framework中,掌握了它们之间的关系和每一个逻辑步骤,你对framework的了解至少有百分之五十

AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要。

在没有深入了解AMS与WMS前,对它俩负责的功能一直很模糊,一直搞不清区别。所以在深入理解其中之一时,先对它们在Android中各自负责的任务有个基本的了解和区分。

  • AMS和WMS都属于Android中的系统服务,系统服务有很多,它们在Android体系架构中都属于同一层次,所以最好在深入了解它们各自的运行机理前,对系统的宏观架构能够有所掌握,也就是在自己的脑海中能够搭建一个简单的模型和框架,搞清楚它们在系统中所扮演的角色。

下面先简单对AMS与WMS作个简单的介绍:

Activity与WIndow:

  • Activity只负责生命周期和事件处理
  • Window只控制视图
  • 一个Activity包含一个Window,如果Activity没有Window,那就相当于Service

AMS与WMS:

  • AMS统一调度所有应用程序的Activity
  • WMS控制所有Window的显示与隐藏以及要显示的位置

在视图层次中,Activity在WIndow之上,如下图
在这里插入图片描述

2. WMS

WindowManagerService服务的实现是相当复杂的,毕竟它要管理的整个系统所有窗口的UI,而在任何一个系统中,窗口管理子系统都是极其复杂的。

作用:

  • 为所有窗口分配Surface。客户端向WMS添加一个窗口的过程,其实就是WMS为其分配一块Suiface的过程,一块块Surface在WMS的管理下有序的排布在屏幕上。Window的本质就是Surface。
  • 管理Surface的显示顺序、尺寸、位置
  • 管理窗口动画
  • 输入系统相关:WMS是派发系统按键和触摸消息的最佳人选,当接收到一个触摸事件,它需要寻找一个最合适的窗口来处理消息,而WMS是窗口的管理者,系统中所有的窗口状态和信息都在其掌握之中,完成这一工作不在话下。

什么是Window?

  • “Window”表明它是和窗口相关的,“窗口”是一个抽象的概念,从用户的角度来讲,它是一个“界面”;从SurfaceFlinger的角度来看,它是一个Layer,承载着和界面有关的数据和属性;从WMS角度来看,它是一个WIndowState,用于管理和界面有关的状态。
  • 在《深入理解Android内核设计思想》一书中看到一个比喻非常好,整个界面就像由N个演员参与的话剧:SurfaceFling是摄像机,它只负责客观的捕捉当前的画面,然后真实的呈现给观众;WMS就是导演,它要负责话剧的舞台效果、演员站位;ViewRoot就是各个演员的长相和表情,取决于它们各自的条件与努力。可见,WMS与SurfaceFling的一个重要区别就是——后者只做与“显示”相关的事情,而WMS要处理对输入事件的派发。
  • Android支持的窗口类型很多,统一可以分为三大类,另外各个种类下还细分为若干子类型,且都在WindowManager.java中有定义。
    • Application Window
    • SystemWindow
    • Sub Window

类间关系:
上面那些都是对WMS相关功能的介绍,对WMS有个感性的认识,现在开始进入相关类。

主要使用的桥接模式,具体自行学习
在这里插入图片描述
一个问题:

WMS是系统服务,有SystemServer负责启动,启动时机相对较晚,那么在WMS运行之前,终端显示屏就一团黑?

  • 在WMS启动之前,系统只需显示开机动画,它们都有特殊的方式来向屏幕输出图像,比如直接通过OpenGL ES与SurfaceFling的配合来完成。
  • 这也从侧面告诉我们,要想在Android上显示UI,并不一定要通过WMS。

3. AMS

作用:

  • 统一调度所有应用程序的Activity的生命周期
  • 启动或杀死应用程序的进程
  • 启动并调度Service的生命周期
  • 注册BroadcastReceiver,并接收和分发Broadcast
  • 启动并发布ContentProvider
  • 调度task
  • 处理应用程序的Crash
  • 查询系统当前运行状态

类间关系:

主要使用了代理模式,具体可以看我的另外一篇博文:设计模式——代理模式.
在这里插入图片描述

  • ActivityManagerProxy和ActivityManagerNative都实现了IActivityManager,ActivityManagerProxy就是代理部分,ActivityManagerNative就是实现部分
  • 但ActivityManagerNative是个抽象类,并不处理过多的具体逻辑,大部分具体逻辑是由ActivityManagerService承担,这就是为什么我们说真实部分应该为ActivityManagerService。

启动流程:

  • 第一阶段:启动ActivityManagerService。
  • 第二阶段:调用setSystemProcess。
  • 第三阶段:调用installSystemProviders方法。
  • 第四阶段:调用systemReady方法。

工作流程:

  • AMS的工作流程,其实就是Activity的启动和调度的过程,所有的启动方式,最终都是通过Binder机制的Client端,调用Server端的AMS的startActivityXXX()系列方法。所以可见,工作流程又包括Client端和Server端两个。

Client端流程:

  • auncher主线程捕获onClick()点击事件后,调用Launcher.startActivitySafely()方法。Launcher.startActivitySafely()内部调用了Launcher.startActivity()方法,Launcher.startActivity()内部调用了Launcher的父类Activity的startActivity()方法。
  • Activity.startActivity()调用Activity.startActivityForResult()方法,传入该方法的requestCode参数若为-1,则表示Activity启动成功后,不需要执行Launcher.onActivityResult()方法处理返回结果。
  • 启动Activity需要与系统ActivityManagerService交互,必须纳入Instrumentation的监控,因此需要将启动请求转交instrumentation,即调用Instrumentation.execStartActivity()方法。
  • nstrumentation.execStartActivity()首先通过ActivityMonitor检查启动请求,然后调
  • ActivityManagerNative.getDefault()得到ActivityManagerProxy代理对象,进而调用该代理对象的startActivity()方法。
  • ActivityManagerProxy是ActivityManagerService的代理对象,因此其内部存储的是BinderProxy,调用ActivityManagerProxy.startActivity()实质是调用BinderProxy.transact()向Binder驱动发送START_ACTIVITY_TRANSACTION命令。Binder驱动将处理逻辑从Launcher所在进程切换到ActivityManagerService所在进程。

Server端流程:

启动Activity的请求从Client端传递给Server端后,便进入了启动应用的七个阶段,这里也是整理出具体流程,细节可以参考《Android的设计与实现》第十一章内容。

预启动:

  • ActivityManagerService.startActivity()
  • ActivityStack.startActivityMayWait()
  • ActivityStack.startActivityLocked()
  • ActivityStack.startActivityUncheckedLocked()
  • ActivityStack.startActivityLocked()(重载)
  • ActivityStack.resumeTopActivityLocked()

暂停:

  • ActivityStack.startPausingLocked()
  • ApplicationThreadProxy.schedulePauseActivity()
  • ActivityThread.handlePauseActivity()
  • ActivityThread.performPauseActivity()
  • ActivityManagerProxy.activityPaused()
  • completePausedLocked()

启动应用程序进程:

  • 第二次进入ActivityStack.resumeTopActivityLocked()
  • ActivityStack.startSpecificActivityLocked()
  • startProcessLocked()
  • startProcessLocked()(重载)
  • Process.start()

加载应用程序Activity:

  • ActivityThread.main()
  • ActivityThread.attach()
  • ActivityManagerService.attachApplication()
  • ApplicationThread.bindApplication()
  • ActivityThread.handleBindApplication()

显示Activity:

  • ActivityStack.realStartActivityLocked()
  • ApplicationThread.scheduleLaunchActivity()
  • ActivityThead.handleLaunchActivity()
  • ActivityThread.performLaunchActivity()
  • ActivityThread.handleResumeActivity()
  • ActivityThread.performResumeActivity()
  • Activity.performResume()
  • ActivityStack.completeResumeLocked()

Activity Idle状态的处理

停止源Activity:

  • ActivityStack.stopActivityLocked()
  • ApplicationThreadProxy.scheduleStopActivity()
  • ActivityThread.handleStopActivity()
  • ActivityThread.performStopActivityInner()

以上是关于Android进阶——WMS与AMS浅析的主要内容,如果未能解决你的问题,请参考以下文章

WMS深入浅出

android 11/12的 framework 框架systemserver源码中的AMS和WMS部分ProtoLog相关log的开放命令

android 11/12的 framework 框架systemserver源码中的AMS和WMS部分ProtoLog相关log的开放命令

2022金三银四Android面试必备知识点:Android AMS/WMS/Binder/Hander

Android进阶——AMS详解

不服不行!终于有人把AMS和WMS讲明白了!