Android AMS介绍

注:本文为作者学习笔记,如有误,请各位大佬指点

系统进程运行环境的初始化

  • Context是一个抽象类,它可以访问application环境的全局信息和各种资源信息和类

  • context功能:

    • 对Activity、Service生命周期的管理
    • 通过Intent发送广播/注册广播接收者
    • 访问APK各种资源,比如Reservice、AssertManager等
    • 访问Package的相关资源
    • APK的权限管理
  • Android进程分为:

    • 应用进程

      ActivityThread就是应用进程的主线程,

      应用进程启动后,首先会执行ActivityThread的main(),

      应用程序也是通过ActivityThread来和AMS通信,调用和执行四大组件。

    • 系统进程

      SystemServer是Android的系统进程,

      由于它也有Activity和一些系统资源,所以为了保证调用方式的统一,它也需要Activity和Context等运行环境,所以SystemServer也是一个特殊的应用程序。

  • 系统Context的创建过程

    在启动SystemServer启动之后,执行createSystemContext(),

    在这个方法内部会完成系统进程运行环境的初始化,包括创建ActivityThread线程,ResourcesManager对象的创建和初始化,LoadedAPK的创建和初始化,LoadedAPK代表一个系统进程的APK,它里面存储资源的位置、JNI包的位置等,代表的就是Framework-res-apk,ContextImpl的构造方法创建一个Context,会将ResourcesManager、LoadedAPK加载进去,最终生成一个和系统进程相关的Context。

    ActivityThread和Context就构成了Android程序的运行环境。

ActivityThread、ApplicationThread

ActivityThread

​ 代表Android的主线程(不是线程类),系统创建完一个新的应用程序后,会在这个进程的主线程中调用ActivityThread的main(),里面会执行一个loop的循 环,使当前线程进入消息循环。

​ 所以Android应用进程的入口函数是ActivityThread的main(),就是一个ActivityThread类对应一个应用程序进程。

ApplicationThread

​ 是ActivityThread的内部类, 是一个Binder对象。在此处它是作为IApplicationThread对象 的server端,等待client端的请求,然后进行处理,最大的client就是AMS。

AMS是啥

  • AMS是什么

    位于应用框架层,负责系统中四大组件的启动、切换、调度,及应用进程的管理和调度工作

  • 什么时候初始化?

    在SystemServer进程开启的时候,就会初始化AMS

  • 简介

    • AMS通过使用一些系统资源和数据结构(如进程、任务栈、记录Activity生命周期的状态机等)来管理Activity生命周期。

    • 当用户在设备上执行新的操作时,AMS会找到相应的任务栈,并根据其优先级来判断应该启动哪个Activity。

    • AMS也负责检查和处理系统内存的使用情况,并根据需要重新排列和重组任务栈中的Activity。

    • ActivityTaskManagerService(ATMS)是Android 10 新增的系统服务类,ATMS承担了AMS的部分工作(activities、task、stacks、display相关),比如将activity的启动相关的调用转移到ATMS了。

  • AMS功能

    • 组件状态管理

      包括四大组件的开启、关闭等(比如startActivity、startActivityAndWait、activityPaused、stopActivity、removeContentProvide)

    • 组件状态查询

      查询组件当前运行等情况(比如getCallingActivity、getService)

    • Task相关

      包括removeTask、removeSubTask、moveTaskBackwards、moveTaskToFront等

    • AMS是通过ActivityStack及其他数据结构佬记录,管理系统中的activity及其他组件的状态,并提供查询功能的一个系统服务

AMS原理

  • 应用程序启动过程

    点击应用程序图标时,由Launcher应用程序向AMS发送一个启动请求。

    AMS根据包名和类名找到对应的Activity,并启动activity。

    AMS在启动activity过程中,会创建activity所在的进程,并控制生命周期。

  • Activity生命周期的管理

    AMS通过与Zygote进行通信,创建Activity实例,

    然后根据activity的状态来管理它的运行状态,

    当应用程序处于后台时,AMS会将其进程变成缓存进程,

    当内存不足时,AMS会杀死缓存进程。

    AMS还负责监测应用程序的内存使用情况,内存不足,就会根据优先级来终止一些应用程序的Activity。

  • 应用程序之间交互

    当用户启动一个新应用程序时,AMS检查该应用程序是否已经在运行,根据需要执行操作:

    如果已经在运行,就直接切换到这个应用程序;

    如果不存在,就启动这个应用程序;

    如果在后台运行,就把它切换到前台。

  • 系统服务的调度

    系统服务包括WI-FI、蓝牙等,AMS会启动、停止、重启这些服务,以保证系统正常运行。

  • 应用程序的任务管理

    将多个应用程序的activity组成一个任务,提供任务导航和管理等功能。

  • 应用程序的权限管理

    当应用程序请求权限时,AMS会弹出对话框询问用户是否授权,

    如果用户授权,就将应用的权限信息存储到系统中。

常用类和方法

  • ActivityManagerService类

    AMS的核心类,负责管理应用程序的生命周期、进程的创建和销毁

    • startProcessLocked() 启动一个新进程
    • killProcessesLocked() 杀死不必要的进程
    • attachApplicationLocked() 将应用程序绑定到AMS
    • handleAppDiedLocked() 处理应用程序死亡事件。
  • ActivityStack类

    管理应用程序的Activity栈(activity任务),一个ActivityStack对应一个Activity任务。

    • startActivityLocked() 启动一个新的Activity
    • moveToBackLocked() 将当前Activity移动到栈底
  • ProcessRecord类

    一个进程实例,负责管理进程的生命周期。进程之间通信采用Binder机制。

    • startProcess() 启动一个新的进程

    • kill() 结束进程

  • ActivityTaskManagerService类

    处理应用程序的Task相关问题。Task是一组相关的Activity集合,他们可以共享一个Back键返回栈,通常处于一个任务栏中。

    • startActivity(Intent intent) 启动指定的Activity,并添加到Task中
    • moveTaskToFront(int taskId, int flags) 将指定的Task移动到前台

SystemServer加载AMS

Zygote进程会创建SystemServer进程,AMS是在SystemServer中启动的:
在这里插入图片描述
在run()里面新建一个SystemServiceManager对象,然后加到本地服务列表中,

接着启动三类服务:引导服务(AMS就是其中一个)、核心服务、其他服务:

  1. 创建AMS对象,并启动服务
  2. 将AMS所在的系统进程添加到进程管理中(完成AMS注册到SystemManager中)
  3. 为系统进程安装ContentProvider对象
  4. 在systemReady方法中做善后
    在这里插入图片描述
    然后启动AMS的主线程Looper,用于处理AMS的各种操作。

App启动中的AMS流程

  1. 用户点击应用程序图标,系统通过Launcher应用程序给AMS发送一个启动应用程序的请求。
  2. AMS接收到启动请求后,先检查应用程序是否已经运行,
    1. 如果已经运行,则直接把应用程序的任务栈置于前台,并把最上层的activity显示在屏幕上。
    2. 如果程序没有运行,ANS就会根据包名和activity类名创建一个新的进程,把它添加到系统的进程列表中。
  3. AMS会在新的进程中创建一个ActivityThread实例,并通过Binder机制与该进程进行通信。
  4. ActivityThread负责处理应用程序的生命周期和界面显示等任务。在创建完ActivityThread实例后,AMS会调用ActivityThread的main()启动该线程的主线程。
  5. 主线程启动后,ActivityThread会初始化应用程序的上下文环境,并加载应用程序的资源,然后ActivityThread会调用Instrumentation的callApplicationOnCreate(),通知应用程序的application实例进行初始化操作。
  6. 应用程序的application实例初始化完成后,ActivityThread会调用Instrumentation的newActivity()创建启动activity的实例,并将其添加到任务栈中。
  7. ActivityThread会调用activity的onCreate(),执行应用程序的初始化逻辑。在这个过程中,activity可以加载布局、注册监听器等。
  8. 当Activity的onCreate()执行完后,ActivityThread会调用activity的onStart(),使activity进入可见状态
  9. 最后,ActivityThread会调用activity的onResume(),使activity进入前台并显示在屏幕上。

通信方式

对于Android上层架构,最常用的通信方式是Binder、Socket、Handler,当然也有少量其他的IPC方式,比如杀进程Process.killProcess() 采用的是signal方式。

为何Android要采用Binder作为IPC机制

  • 管道:在创建时分配一个page大小的内存,缓存区大小比较有限。
  • 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
  • 共享内存:无须复制,共享缓冲区直接附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
  • 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信;
  • 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为 进程间以及同一进程内不同线程之间的同步手段。
  • 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;

使用Binder的理由

Binder跨进程通信的优点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW自动生成NI-DAQmx代码

在现代数据采集和控制系统中,LabVIEW被广泛应用于各种工业和科研领域。其中,NI-DAQmx是一个强大的驱动程序,可以帮助用户高效地管理和配置数据采集任务。本文将介绍如何在LabVIEW中通过DAQ Assistant Express VI和任务常量自动生成NI-DAQmx代…

Python编码系列—Python状态模式:轻松管理对象状态的变化

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

架构演化--将MVC代码重构成DDD

什么是好的代码架构 在当前的工作中我们所面临的主要矛盾是“越来越多的多场景化复杂业务需求与有限的研发人力之间的矛盾”。而要解决这一矛盾,就要求我们的系统能做到:设计易拓展、代码易复用、逻辑易传承、运行更稳定。 设计易拓展 一个好的架构应该…

Ceph RocksDB 深度调优

介绍 调优 Ceph 可能是一项艰巨的挑战。在 Ceph、RocksDB 和 Linux 内核之间,实际上有数以千计的选项可以进行调整以提高存储性能和效率。由于涉及的复杂性,比较优的配置通常分散在博客文章或邮件列表中,但是往往都没有说明这些设置的实际作…

如果您忘记了 Apple ID 和密码,按照指南可重新进入您的设备

即使您的 iPhone 或 iPad 由于各种原因被锁定或禁用,也可以使用 iTunes、“查找我的”、Apple 支持和 iCloud 解锁您的设备。但是,此过程需要您的 Apple ID 和密码来验证所有权并移除激活锁。如果您忘记了 Apple ID 和密码,请按照我们的指南重…

G502 鼠标自定义(配合 karabiner)

朋友送了我一个 G502 多功能鼠标,除了鼠标正常的左键、右键和滑轮外,额外提供了 6 个按键,并且滑轮可以向左、向右、向下按下,共计 9 个自定义的按键。 虽然是 karabiner 的老用户,但一直在使用 TrackPad,所…

SpringGateway(网关)微服务

一.启动nacos 1.查看linux的nacos是否启动 docker ps2.查看是否安装了nacos 前面是你的版本,后面的names是你自己的,我们下面要启动的就是这里的名字。 docker ps -a3.启动nacos并查看是否启动成功 二.创建网关项目 1.创建idea的maven项目 2.向pom.x…

VMware 虚拟机 下载安装 Centos7 和Windows10 镜像源

准备工作 下载 VMware链接:稍后发布链接 Centos7完整版链接:https://www.123865.com/ps/EF7OTd-mdAnH Centos7mini版链接:https://www.123865.com/ps/EF7OTd-1dAnH Windows10链接:https://www.123865.com/ps/EF7OTd-4dAnH 演示环境…

【Git】一文看懂Git

Git 一、简介1. Git 与 SVN 区别1.1 Git 是分布式的,SVN 不是1.1.1 分布式版本控制系统Git1.1.2 集中式版本控制系统SVN 1.2 Git 把内容按元数据方式存储,而 SVN 是按文件1.3 Git 分支和 SVN 的分支不同1.4 Git 没有一个全局的版本号,而 SVN …

CS 工作笔记:SmartEdit 里创建的是 CMS Component

下图是在 SmartEdit 里创建的 cms Component,在 Back-Office 里的截图: SAP Commerce Cloud 的 CMS Component 是其内容管理系统 (CMS) 的核心组成部分,它提供了对在线商店或平台内容的灵活管理。通过这些组件,用户能够在不涉及复…

C# 字符串(String)的应用说明一

一.字符串(String)的应用说明: 在 C# 中,更常见的做法是使用 string 关键字来声明一个字符串变量,也可以使用字符数组来表示字符串。string 关键字是 System.String 类的别名。 二.创建 String 对象的方法说明&#x…

Spark SQL分析层优化

导读:本期是《深入浅出Apache Spark》系列分享的第四期分享,第一期分享了Spark core的概念、原理和架构,第二期分享了Spark SQL的概念和原理,第三期则为Spark SQL解析层的原理和优化案例。本次分享内容主要是Spark SQL分析层的原理…

亚马逊 Bedrock 平台也能使用Llama 3.2 模型了

亚马逊 Bedrock 平台推出 Llama 3.2 模型:多模态视觉和轻量级模型 概述 由 Meta 提供的最新 Llama 3.2 模型现已在 Amazon Bedrock 平台上推出。这一新模型系列标志着 Meta 在大型语言模型(LLM)领域的最新进展,它在多种应用场景…

本地访问autodl的jupyter notebook

建立环境并安装jupyter conda create --name medkg python3.10 source activate medkg pip install jupyter 安装完成后,输入jupyter notebook --generate-config 输入ipython,进入python In [2]: from jupyter_server.auth import passwd In [3]: passwd(algori…

Spring Data(学习笔记)

JPQL语句???(Query括号中的就是JPQL语句) 怎么又会涉及到连表查询呢? 用注解来实现表间关系。 分页是什么?为什么什么都有分页呢 ? 继承,与重写方法的问题 Deque是什么 ?…

【JavaSE】反射、枚举、lambda表达式

目录 反射反射相关类获取类中属性相关方法常用获得类相关的方法示例常用获得类中属性相关的方法示例获得类中注解相关的方法 反射优缺点 枚举常用方法优缺点 枚举与反射lambda表达式语法函数式接口简化规则使用示例变量捕获集合中的应用优缺点 反射 Java的反射(refl…

通信协议感悟

本文结合个人所学,简要讲述SPI,I2C,UART通信的特点,限制。 1.同步通信 UART,SPI,I2C三种串行通讯方式,SPI功能引脚为CS,CLK,MOSI,MISO;I2C功能引…

若依从redis中获取用户列表

因为若依放入用户的时候&#xff0c;会在减值中添加随机串&#xff0c;所以用户的key会在redis中变成&#xff1a; login_tokens:6af07052-b76d-44dd-a296-1335af03b2a6 这样的样子。 如果用 Set<Object> items redisService.redisTemplate.keys("login_tokens&…

dcatadmin 自定义登录页面

一、问题&#xff1a; 在后台管理系统中&#xff0c;不同的项目想要不同的登录页面&#xff0c;但是框架自带的登录页面就只有一个。 解决&#xff1a; 由芒果系统改造的dcatadmin登录插件&#xff0c;实现一键安装改变登录页面。 项目介绍 基于Laravel和Vue的快速开发的后台管…

YOLO11改进 | 检测头 | 小目标遮挡物性能提升的检测头Detect_MultiSEAM【完整代码】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 基于深度学习的人脸检测算法取得了巨大进…