AMS面试
AMS(ActivityManagerService)核心60题
一、AMS 基础概念与整体定位
什么是 AMS?它在 Android 系统中扮演什么角色?
AMS是Android系统Framework层的核心系统服务之一,全称为ActivityManagerService,运行在SystemServer进程中,是系统组件(Activity、Service、BroadcastReceiver、ContentProvider)的统一管控中心,也是连接应用层与系统层的关键枢纽。
其在Android系统中扮演的核心角色主要有两个:一是“组件大管家”,统筹管理所有系统组件的生命周期、运行状态,规范组件的创建、启动、暂停、停止、销毁等行为,确保组件交互有序;二是“系统协调者”,协调各类系统服务(如PMS、WMS、PowerManagerService)协同工作,管控系统资源(CPU、内存)分配,处理进程调度、任务管理等核心逻辑,保障系统整体的稳定性、流畅性,同时拦截非法操作,保障系统安全。
原理:Android系统采用分层架构,应用层组件无法直接操作系统内核资源,必须通过Framework层的系统服务间接交互。AMS作为核心系统服务,通过Binder机制接收应用层的请求(如启动Activity、绑定Service),执行对应管控逻辑,再将处理结果反馈给应用进程,相当于应用层与系统层之间的“中转站”。同时,AMS统一管理组件和进程,避免组件混乱启动、资源滥用,是Android系统正常运行的核心支撑,没有AMS,应用组件无法正常启动和运行。
AMS 的主要功能有哪些?请详细说明每一项核心功能的作用。
AMS的核心功能围绕“管控组件、调度资源、保障稳定、防范风险”展开,共5项核心功能,每一项功能的详细作用如下:
组件生命周期管理(核心功能):负责管控Android系统中所有核心组件(Activity、Service、BroadcastReceiver、ContentProvider)的全生命周期,严格控制组件生命周期方法的执行顺序,确保组件状态切换规范。例如,启动Activity时,严格触发onCreate→onStart→onResume的顺序;暂停Activity时,先触发onPause,再执行后续组件的启动逻辑;销毁Activity时,按onPause→onStop→onDestroy的顺序执行,确保组件资源正常释放。同时,管控Service的启动、绑定、停止,BroadcastReceiver的注册与触发,ContentProvider的创建与访问,避免组件生命周期混乱导致的内存泄漏或功能异常。
进程管理:负责应用进程的全流程管控,是保障系统资源合理分配的核心功能。具体作用包括:
① 进程创建:当需要启动组件且组件所属进程未启动时,AMS通过Binder向Zygote进程发送孵化请求,由Zygote fork出新的应用进程,初始化应用环境(启动ActivityThread);
② 进程优先级管理:根据组件的运行状态,将进程分为5个优先级(前台进程、可见进程、服务进程、后台进程、空进程),动态调整进程优先级,优先为高优先级进程分配CPU、内存资源;
③ 进程调度:协调不同进程的运行顺序,确保前台进程的流畅性,限制后台进程的资源占用;
④ 进程销毁:主动终止异常进程、用户手动停止的进程,或在系统低内存时,按优先级+LRU算法回收低优先级进程,释放系统资源,避免内存溢出。
任务栈管理:负责创建、切换、销毁任务栈(Task Stack),管理栈内Activity的排序与状态,实现多任务切换和应用跳转逻辑。具体作用包括:
① 任务栈创建:启动新应用或新Activity(不满足复用条件)时,创建对应的Task Stack,将Activity压入栈顶;
② 任务栈管理:维护每个任务栈的状态(前台、后台),记录栈内Activity的顺序,支持任务栈的切换(用户切换应用)、合并、分离;
③ 跳转与回退控制:通过任务栈的“先进后出”特性,控制Activity的跳转(压入栈顶)和回退(弹出栈顶),确保用户操作符合预期,同时保存任务栈状态,应用退后台后再次启动时,能恢复到之前的界面状态。
系统服务协调:作为系统服务的核心枢纽,协调AMS与其他系统服务的协同工作,确保各项系统功能正常运行。具体交互场景包括:
① 与PackageManagerService(PMS):启动组件前,通过PMS查询组件信息(如Activity是否存在、应用是否安装、权限是否匹配),验证组件合法性;应用安装/卸载后,接收PMS的通知,更新组件管理状态;
② 与WindowManagerService(WMS):启动Activity时,请求WMS创建窗口、分配窗口层级,控制窗口显示与隐藏;切换任务栈时,协同WMS更新界面渲染,确保多任务切换流畅;
③ 与PowerManagerService:根据设备电源状态(休眠、唤醒、低电量),调整组件和进程状态,如休眠时暂停前台Activity,低电量时优先回收后台进程;
④ 与NotificationManagerService:接收通知相关请求,管控通知的显示与清除,同时根据通知优先级调整进程优先级(如收到通知时,提升应用进程优先级)。
权限与安全检查:负责拦截非法操作,保障系统和用户数据安全,是AMS的核心安全功能。具体作用包括:
① 组件启动检查:启动Activity、Service等组件时,检查应用是否拥有对应的权限(如启动系统Activity需具备系统权限,跨应用启动需具备对应权限),无权限则拦截启动请求;
② 跨进程通信检查:处理跨进程请求时,验证请求进程的合法性,防止恶意进程调用AMS服务,篡改系统状态或获取敏感数据;
③ 应用操作限制:限制应用的非法操作,如禁止后台应用随意启动Activity、禁止未授权应用访问系统资源,保障系统稳定和用户隐私。
原理:AMS的各项核心功能相互关联、相互支撑,组件生命周期管理依赖进程管理(组件需运行在进程中),任务栈管理是组件生命周期管理的延伸(Activity状态与任务栈位置直接相关),系统服务协调是所有功能正常执行的基础,权限与安全检查则是保障系统安全的最后一道防线,五项功能共同构成AMS的完整管控体系,支撑Android系统的正常运行。
二、AMS 启动流程与系统架构关系
AMS 是如何启动的?它的启动流程是什么样的?
AMS不能独立启动,其启动依赖Android系统的整体启动流程,全程由SystemServer进程触发和管理,具体启动流程分为5个核心步骤,环环相扣,确保AMS初始化完成并正常运行:
系统启动前置:Android设备开机后,首先执行BootLoader(引导程序),引导启动Linux内核;Linux内核启动后,会创建第一个用户空间进程——init进程,init进程负责初始化系统环境(如挂载文件系统、启动系统服务),并启动Zygote进程(系统所有进程的父进程)。
Zygote进程初始化:Zygote进程启动后,会执行以下操作:
① 预加载系统核心类(如Framework层的核心API)、系统资源(如framework-res.apk),避免后续进程重复加载,提升进程启动效率;
② 启动Binder驱动,初始化Binder通信机制(AMS的跨进程通信依赖Binder);
③ 注册自身到ServiceManager,供其他进程调用;
④ 进入循环等待状态,接收进程孵化请求。
SystemServer进程孵化:Zygote进程通过fork(进程孵化)方式,创建SystemServer进程(系统服务的宿主进程);SystemServer进程启动后,会初始化自身环境,包括启动Binder线程池、初始化系统上下文(Context)、加载系统配置等,为后续启动系统服务做准备。
AMS启动与初始化:SystemServer进程初始化完成后,通过SystemServiceManager(系统服务管理器)启动各类系统服务,AMS是其中优先级较高的核心服务,具体初始化流程包括:
① 创建AMS实例,初始化核心管理模块,包括ActivityStackSupervisor(任务栈管理器,负责管理所有任务栈)、ProcessRecord(进程管理对象,记录进程信息)、ActivityRecord(Activity管理对象,记录Activity状态)、IntentResolver(Intent解析器,负责解析启动参数)等;
② 注册AMS到ServiceManager,暴露AMS的服务接口,让其他进程(如应用进程、其他系统服务)能通过Binder获取AMS的代理对象,发起请求;
③ 初始化任务栈、进程优先级列表等核心数据结构,启动AMS的核心线程(如用于处理组件启动请求的线程);
④ 关联其他系统服务,通过ServiceManager获取PMS、WMS等服务的代理对象,建立通信通道,确保后续协同工作。
AMS就绪运行:AMS初始化完成后,会向SystemServer发送就绪通知,SystemServer确认AMS就绪后,继续启动其他系统服务;AMS进入正常运行状态,开始接收应用层的各类请求(如启动Activity、创建进程、切换任务栈等),执行对应管控逻辑,完成后续的组件和进程管理工作。
原理:AMS的启动流程严格遵循Android系统的分层架构和进程孵化机制,Zygote进程负责提供进程孵化的基础环境,SystemServer作为宿主进程承载AMS,AMS的初始化过程本质是创建核心管理对象、建立通信通道、注册服务,为后续的管控工作奠定基础。由于AMS依赖Binder机制、其他系统服务(如PMS),因此必须在Zygote和SystemServer启动完成后,才能完成自身初始化,确保各项功能正常运行。
Zygote、SystemServer 与 AMS 之间的关系是什么?三者如何协作?
Zygote、SystemServer与AMS三者是Android系统核心架构的重要组成部分,三者分工明确、相互依赖、协同工作,构成Android系统组件和进程管理的核心体系,具体关系和协作流程如下:
一、核心关系
Zygote与SystemServer:Zygote是SystemServer的父进程,SystemServer由Zygote通过fork方式孵化而来;Zygote为SystemServer提供预加载的系统类、资源和Binder驱动,避免SystemServer重复加载资源,提升启动效率;SystemServer是Zygote孵化的第一个核心子进程,也是所有系统服务的宿主。
SystemServer与AMS:SystemServer是AMS的宿主进程,AMS是SystemServer启动的核心系统服务之一,运行在SystemServer进程中;SystemServer通过SystemServiceManager启动、管理AMS,为AMS提供运行环境(如进程空间、Binder线程池);AMS依赖SystemServer获取其他系统服务(如PMS、WMS)的引用,同时向SystemServer反馈系统状态(如进程占用、资源使用情况)。
Zygote与AMS:Zygote与AMS无直接父子关系,AMS依赖Zygote完成应用进程的孵化;AMS是Zygote的“使用者”,当需要创建应用进程时,AMS向Zygote发送请求,Zygote负责孵化进程,AMS负责后续的进程管理;Zygote不直接参与组件和进程的管控,仅提供进程孵化能力。
二、协同流程
启动阶段协同:
① 设备开机后,init进程启动Zygote;
② Zygote预加载资源、初始化Binder,孵化SystemServer;
③ SystemServer初始化后,通过SystemServiceManager启动AMS,AMS完成初始化并注册到ServiceManager;
④ AMS启动完成后,向Zygote注册进程孵化请求的接收通道,准备后续创建应用进程。
应用进程创建协同:
① 当用户点击应用图标启动Activity时,应用进程(若未启动)会向AMS发送启动请求;
② AMS接收请求后,检查该应用对应的进程是否已存在,若不存在,通过Binder向Zygote发送进程孵化请求,携带应用包名、进程名、UID(用户ID)等参数;
③ Zygote接收请求后,fork出新的应用进程,初始化应用环境(启动ActivityThread,加载应用类和资源);
④ 应用进程启动后,通过Binder向AMS注册自身,AMS创建ProcessRecord对象,记录该进程的ID、优先级、关联组件等信息,将其纳入统一管理;
⑤ 应用进程注册完成后,AMS向其发送Activity启动指令,应用进程执行Activity的生命周期方法,完成启动。
系统运行阶段协同:
① 系统运行过程中,AMS负责管控应用进程的优先级、组件的生命周期、任务栈的切换,当需要调用其他系统服务(如验证组件、显示窗口)时,通过SystemServer获取PMS、WMS的代理对象,发起交互请求;
② SystemServer统筹管理AMS与其他系统服务,协调服务间的资源分配,处理系统级的事件(如关机、重启),当系统资源不足时,通知AMS执行进程回收;
③ Zygote持续处于循环等待状态,接收AMS的进程孵化请求,孵化新的应用进程,同时维护自身的预加载资源,确保进程孵化效率;
④ 当应用进程异常退出时,AMS会通知Zygote(若需要重启进程),Zygote重新孵化进程,AMS恢复该进程的组件状态,保障应用正常运行。
原理:三者的协同核心是“分工明确、依赖支撑”——Zygote负责“进程孵化”,提供基础环境;SystemServer负责“服务宿主”,统筹系统服务;AMS负责“管控核心”,管理组件和进程。三者相互配合,确保Android系统的组件能正常启动、进程能合理调度、系统能稳定运行,缺一不可。
AMS 如何管理系统服务的启动和停止?核心管理机制是什么?
AMS对系统服务的管理并非独立完成,而是依赖SystemServiceManager(系统服务管理器),遵循“统一启动、分级依赖、异常处理、有序停止”的核心逻辑,全程管控系统服务的启动、运行、停止,确保系统服务间协同高效,具体管理方式和核心机制如下:
一、系统服务的启动管理
启动触发:系统服务的启动由SystemServer进程统一触发,SystemServer初始化完成后,通过SystemServiceManager启动所有系统服务,AMS自身也是被SystemServiceManager启动的服务之一;启动顺序严格遵循“依赖优先”原则,即先启动被其他服务依赖的服务,再启动依赖该服务的服务(如先启动PMS,再启动AMS,因为AMS启动需要依赖PMS验证组件信息;先启动AMS,再启动WMS,因为WMS需要与AMS协同管理窗口)。
启动流程:
① SystemServiceManager接收SystemServer的启动指令,根据服务的依赖关系,排序启动列表;
② 依次创建每个系统服务的实例,调用服务的onStart()方法,完成服务自身的初始化(如创建核心模块、注册服务);
③ 服务初始化完成后,注册到ServiceManager,暴露服务接口,供其他服务和应用进程调用;
④ AMS启动完成后,会主动关联所有依赖的系统服务(如PMS、WMS),获取其代理对象,建立通信通道,确保后续协同工作。
启动管控:AMS会监控所有系统服务的启动状态,若某个服务启动失败(如初始化报错、依赖服务未启动),AMS会通知SystemServer,SystemServer会尝试重新启动该服务;若多次启动失败,会触发系统异常处理(如弹出系统错误提示、重启系统),避免单个服务启动失败影响整个系统。
二、系统服务的停止管理
系统服务的停止分为“主动停止”和“异常停止”两种情况,AMS与SystemServiceManager协同处理,确保停止过程规范,避免资源泄漏:
主动停止:
① 系统关机时,SystemServer会触发系统服务的停止流程,调用SystemServiceManager的stopAllServices()方法;
② SystemServiceManager按照“反向启动顺序”,依次调用每个系统服务的onDestroy()方法,让服务清理自身资源(如关闭文件、释放内存、终止线程);
③ AMS收到停止指令后,会先终止所有管理的应用进程、销毁所有任务栈、清理自身核心数据结构(如ProcessRecord、ActivityRecord),然后通知依赖自身的其他服务(如WMS)停止工作,最后执行自身的onDestroy()方法,完成停止;
④ 所有服务停止后,SystemServer进程终止,Zygote进程随之终止,系统完成关机。
异常停止:
① 当某个系统服务出现异常(如崩溃、死锁),SystemServiceManager会检测到服务状态异常,通知AMS;
② AMS会判断该服务的重要性:若为核心服务(如PMS、WMS),AMS会通知SystemServer尝试重启该服务,同时暂停依赖该服务的相关操作(如暂停启动Activity,避免因WMS异常导致窗口显示失败);
③ 若服务重启失败,AMS会触发系统降级策略,关闭非核心功能,保障系统基本运行;若为非核心服务,AMS会直接通知SystemServiceManager终止该服务,清理其资源,避免影响其他服务。
三、核心管理机制
AMS管理系统服务的核心机制是“依赖树管理+状态机管控”,两者结合,确保服务启动有序、运行稳定、停止规范:
依赖树管理机制:SystemServiceManager维护一个系统服务的依赖树,记录每个服务的依赖关系(如AMS依赖PMS、WMS依赖AMS),启动时按依赖树的顺序启动,停止时按反向顺序停止,避免出现“依赖服务未启动,当前服务无法启动”或“依赖服务未停止,当前服务无法停止”的问题。AMS会实时维护依赖树的状态,当某个服务的依赖关系发生变化(如服务升级),AMS会同步更新依赖树,确保管理逻辑正确。
状态机管控机制:AMS为每个系统服务维护一个状态标记(未启动、启动中、已就绪、异常、已停止),通过状态机监控服务的运行状态,实现精细化管控。例如,服务处于“启动中”时,AMS会禁止其他服务调用该服务的接口;服务处于“异常”状态时,AMS会触发重启或终止逻辑;服务处于“已就绪”状态时,AMS会允许其他服务和应用进程调用其接口,确保服务交互有序。
原理:系统服务是Android系统的核心组成部分,多个服务之间存在复杂的依赖关系,若管理不当,会导致服务启动失败、系统崩溃、资源泄漏等问题。AMS通过依赖树管理,确保服务启动和停止的顺序正确;通过状态机管控,实时监控服务状态,及时处理异常,同时协同SystemServiceManager,实现系统服务的统一管理,保障系统整体的稳定性。
三、AMS 通信机制(Binder / 跨进程)
AMS 如何使用 Binder 完成跨进程通信?具体通信流程是什么?
AMS作为Android系统的核心服务,需要与多个应用进程、其他系统服务(运行在SystemServer进程,本质也是跨进程)通信,其跨进程通信的核心依赖Binder机制,Binder具有高效、安全、面向对象的特点,能满足AMS高并发、高安全的通信需求。AMS使用Binder完成跨进程通信的核心逻辑是:AMS作为Binder服务端,暴露服务接口;请求方(应用进程、其他服务)作为Binder客户端,通过ServiceManager获取AMS的Binder代理对象,发起请求,实现双向通信。具体通信流程分为6个核心步骤,以“应用进程启动Activity”为例,详细说明:
服务端注册(AMS注册):AMS启动时,会创建Binder实例(具体为ActivityManagerNative类的实例,该类继承自Binder,实现了AMS的服务接口);然后将该Binder实例注册到ServiceManager(系统服务注册表),同时注册服务名称(android.app.ActivityManager),让其他进程能通过该名称获取AMS的Binder代理对象。此时,AMS作为Binder服务端,进入等待请求状态,Binder线程池开始监听客户端的请求。
客户端获取代理(应用进程获取AMS代理):应用进程启动后,需要启动Activity时,会通过Context的getSystemService()方法,获取AMS的服务引用;底层会通过ServiceManager,根据服务名称(android.app.ActivityManager),查询到AMS的Binder代理对象(具体为ActivityManagerProxy类的实例,该类实现了与AMS服务端对应的接口);应用进程获取到该代理对象后,即可通过代理对象向AMS发起请求。
客户端发起请求(应用进程发送启动Activity请求):应用进程通过AMS的Binder代理对象,调用startActivity()方法,将启动请求的参数(如Intent、Activity组件信息、启动模式等)封装为Parcel对象(Binder通信的序列化格式,支持跨进程传输);然后通过Binder驱动,将Parcel对象发送给AMS服务端。此时,客户端(应用进程)会阻塞,等待服务端的响应(若为异步请求,不会阻塞)。
服务端接收请求(AMS接收请求):AMS服务端的Binder线程池监听到底层的请求后,将请求转发给AMS实例;AMS实例接收Parcel对象,解析其中的请求参数(如解析Intent中的目标Activity、启动模式等),执行对应的管控逻辑(如检查组件合法性、判断是否需要创建进程、调整任务栈等)。
服务端反馈结果(AMS返回处理结果):AMS执行完管控逻辑后,将处理结果(如启动成功、启动失败、需要创建进程等)封装为Parcel对象,通过Binder驱动,返回给应用进程的Binder代理对象;若启动成功,AMS会向应用进程发送后续的Activity生命周期触发指令(如onCreate、onStart)。
客户端处理结果(应用进程执行后续操作):应用进程的Binder代理对象接收Parcel对象,解析处理结果;若启动成功,应用进程根据AMS的指令,执行Activity的生命周期方法,完成Activity的启动;若启动失败(如权限不足、Activity不存在),应用进程会收到异常提示,执行对应的错误处理逻辑(如弹出提示框)。
补充:AMS与其他系统服务(如PMS、WMS)的通信流程类似,由于其他系统服务也运行在SystemServer进程,本质是进程内的Binder通信,但流程与跨进程通信一致(注册服务、获取代理、发起请求、反馈结果),只是通信效率更高(无需跨进程切换)。
原理:Binder机制是Android跨进程通信的核心,基于Client/Server(客户端/服务端)模式,通过共享内存实现数据传输,比传统的IPC机制(如管道、Socket)更高效。AMS作为服务端,通过注册Binder实例到ServiceManager,暴露服务接口;客户端通过获取代理对象,发起请求,实现跨进程通信。同时,Binder具有权限校验机制,能验证客户端的合法性,避免恶意进程调用AMS服务,保障系统安全,这也是AMS选择Binder作为通信机制的核心原因。
如何通过 AMS 实现进程间的通信?核心依赖什么机制?具体流程是什么?
通过AMS实现进程间通信,核心是借助AMS的“中间转发”能力,结合Binder机制,实现两个应用进程之间的间接通信(AMS作为中转枢纽),无需两个进程直接建立Binder连接,简化通信流程,同时由AMS进行权限校验,保障通信安全。其核心依赖的机制是“Binder跨进程通信机制+AMS的组件管控机制”,其中Binder负责数据传输,AMS负责中转请求、校验权限、协调进程状态,具体流程以“进程A启动进程B的Activity”为例,详细说明(这是最常见的通过AMS实现跨进程通信的场景):
发起方准备(进程A发起请求):进程A需要启动进程B的Activity时,创建Intent对象,指定目标Activity的组件信息(包名、类名),同时可携带需要传递的数据(通过Intent的putExtra()方法);然后调用startActivity()方法,发起启动请求,该请求会被底层封装,发送给AMS。
AMS中转与校验(AMS处理请求):
① AMS通过Binder接收进程A的请求,解析Intent中的组件信息,通过PMS验证目标Activity(进程B的Activity)是否存在、是否允许被进程A启动(权限校验);
② 若校验通过,AMS判断进程B是否已启动:若未启动,AMS通过Zygote孵化进程B,进程B启动后向AMS注册自身;若已启动,直接获取进程B的进程信息;
③ AMS将进程A传递的Intent数据(通过Parcel序列化)转发给进程B,同时向进程B发送启动Activity的指令,告知其启动目标Activity,并传递相关参数。
接收方处理(进程B执行操作):进程B通过Binder接收AMS的指令和Intent数据,解析数据后,启动目标Activity,执行对应的业务逻辑(如根据Intent中的数据显示内容);若需要向进程A反馈结果(如Activity启动成功、处理完成),进程B会通过Binder向AMS发送反馈信息,再由AMS将反馈信息转发给进程A。
通信结束(流程闭环):进程B完成Activity启动后,向AMS发送“启动完成”的反馈,AMS更新组件和进程状态,通知进程A启动请求处理完成;进程A接收反馈后,可继续执行后续操作(如隐藏自身Activity),整个跨进程通信流程完成。
补充:除了启动Activity,通过AMS实现跨进程通信的场景还有“进程A绑定进程B的Service”“进程A发送广播给进程B的BroadcastReceiver”,核心流程一致,均为“进程A→AMS→进程B”的中转模式,由AMS负责校验、转发和状态协调。
核心依赖机制详解:
Binder跨进程通信机制:这是基础机制,负责进程间的数据传输(Intent数据、指令、反馈结果),通过Parcel序列化/反序列化,实现数据的跨进程传递;同时,Binder的Client/Server模式,确保AMS能作为服务端,接收多个进程的请求,实现中转。
AMS的组件管控机制:AMS作为组件大管家,能管控所有进程的组件状态,确保进程B能及时接收AMS转发的请求,同时能校验进程A的权限,避免非法通信;此外,AMS能孵化进程B(若未启动),确保通信的正常进行,无需进程A手动处理进程B的启动逻辑,简化通信流程。
原理:两个应用进程之间无法直接通信(Android系统的进程隔离机制),必须通过中间媒介(系统服务)实现间接通信。AMS作为核心系统服务,具备管控所有进程和组件的能力,同时依赖Binder机制实现跨进程数据传输,因此成为进程间通信的理想中转枢纽。通过AMS中转,不仅简化了进程间通信的流程(无需手动建立Binder连接),还能通过AMS的权限校验,保障通信安全,避免恶意进程窃取数据或发起非法请求。
四、AMS 与其他系统服务交互
AMS 如何与其他系统服务(如 PackageManagerService、WindowManagerService、WMS)交互?核心交互场景有哪些?
AMS作为Android系统的核心协调者,与其他系统服务的交互均基于Binder机制(即使服务运行在同一个SystemServer进程,也通过Binder调用规范交互),核心逻辑是:AMS通过ServiceManager获取其他系统服务的Binder代理对象,调用其暴露的接口发起请求;其他系统服务也通过ServiceManager获取AMS的代理对象,向AMS反馈状态或发起请求,形成双向交互。不同系统服务的交互场景不同,核心围绕“组件管控、资源分配、界面显示”展开,以下详细说明与核心系统服务的交互方式和场景:
一、与PackageManagerService(PMS)的交互
PMS是Android系统中负责应用安装、卸载、组件信息管理的核心服务,AMS与PMS的交互最频繁,核心是“组件合法性校验”和“组件信息获取”,具体交互场景和方式:
交互方式:AMS启动后,通过ServiceManager获取PMS的Binder代理对象(PackageManagerProxy),通过该代理对象调用PMS的接口(如getPackageInfo()、resolveActivity());PMS也会通过ServiceManager获取AMS的代理对象,当应用安装/卸载、组件信息变化时,向AMS发送通知,同步更新组件管理状态。
核心交互场景:
① 组件启动校验:启动Activity、Service、BroadcastReceiver等组件时,AMS通过PMS查询组件信息(如组件是否存在、应用是否安装、是否具备启动权限、组件的process属性的等),若校验失败,拦截启动请求;
② 组件信息获取:AMS需要获取应用的包信息、组件列表、权限信息时,调用PMS的接口,如获取Activity的启动模式、Service的绑定方式等,用于后续的组件管控;
③ 应用安装/卸载同步:当PMS完成应用安装或卸载后,会通知AMS,AMS同步清理该应用的进程(若已启动)、任务栈、组件记录,避免残留资源;
④ 权限校验:启动组件或跨进程通信时,AMS通过PMS查询应用的权限状态,判断是否允许执行对应操作,如跨应用启动Activity需校验LAUNCHER权限。
二、与WindowManagerService(WMS)的交互
WMS是Android系统中负责窗口管理、界面渲染的核心服务,AMS与WMS的交互核心是“Activity显示管控”和“多任务切换协同”,两者协同完成应用界面的显示与切换,具体交互场景和方式:
交互方式:AMS启动后,通过ServiceManager获取WMS的Binder代理对象(WindowManagerProxy),向WMS发送窗口创建、显示、隐藏、切换等请求;WMS也会向AMS反馈窗口状态(如窗口是否显示、窗口大小变化),AMS根据窗口状态调整组件和进程优先级。
核心交互场景:
① Activity窗口创建与显示:启动Activity时,AMS完成组件初始化后,向WMS发送窗口创建请求,传递Activity的窗口参数(如大小、位置、层级);WMS创建窗口,分配窗口ID,将窗口添加到窗口层级中,完成界面渲染,让Activity显示在屏幕上;
② 多任务切换:用户切换应用时,AMS切换任务栈的前台/后台状态,同时通知WMS切换对应窗口的显示状态(前台任务栈的窗口显示,后台任务栈的窗口隐藏),WMS同步更新界面渲染,确保切换流畅;
③ Activity暂停/恢复与窗口联动:当Activity暂停(onPause)时,AMS通知WMS隐藏该Activity的窗口;当Activity恢复(onResume)时,AMS通知WMS显示该窗口,确保窗口状态与Activity状态一致;
④ 窗口层级管理:AMS根据Activity的优先级,向WMS传递窗口层级参数,WMS按层级显示窗口(如前台Activity的窗口层级最高,弹窗窗口层级高于普通窗口),避免窗口遮挡异常。
三、与PowerManagerService(PMS,与PackageManagerService重名,通常简称PowerMS)的交互
PowerMS是Android系统中负责电源管理、设备状态管控的核心服务,AMS与PowerMS的交互核心是“根据设备电源状态调整组件和进程行为”,具体交互场景和方式:
交互方式:AMS通过ServiceManager获取PowerMS的代理对象,查询设备电源状态(如休眠、唤醒、低电量),接收PowerMS发送的电源状态变化通知;PowerMS也会根据AMS的请求,调整设备电源状态(如唤醒设备、进入休眠)。
核心交互场景:
① 设备休眠/唤醒处理:当PowerMS检测到设备进入休眠状态时,通知AMS,AMS暂停前台Activity(调用onPause、onStop),降低进程优先级,停止非必要的组件操作(如后台Service);当设备唤醒时,AMS恢复前台Activity(调用onRestart、onStart、onResume),提升进程优先级,恢复组件运行;
② 低电量处理:当PowerMS检测到设备低电量时,通知AMS,AMS启动低内存回收策略,优先回收后台进程、空进程,释放内存,同时限制后台组件的资源占用(如禁止后台Activity启动),延长设备续航;
③ 屏幕亮灭联动:当屏幕熄灭时,AMS通知WMS隐藏所有窗口,暂停前台组件;当屏幕点亮时,AMS通知WMS显示前台窗口,恢复组件运行。
四、与NotificationManagerService(NMS)的交互
NMS是Android系统中负责通知管理的核心服务,AMS与NMS的交互核心是“通知显示与进程优先级联动”,具体交互场景和方式:
交互方式:AMS通过ServiceManager获取NMS的代理对象,发送通知显示、清除请求;NMS收到通知相关操作时,向AMS反馈通知状态,AMS根据通知优先级调整应用进程优先级。
核心交互场景:
① 通知显示管控:应用发送通知时,通过AMS向NMS发送请求,AMS先校验应用的通知权限,若有权限,转发请求给NMS,NMS显示通知;
② 进程优先级调整:当应用发送通知(尤其是前台通知)时,NMS通知AMS,AMS提升该应用的进程优先级(从后台进程提升为可见进程或前台进程),避免进程被回收,确保用户能及时看到通知;
③ 通知点击处理:用户点击通知时,NMS通知AMS,AMS启动通知对应的Activity(如点击微信通知启动微信Activity),完成通知跳转逻辑。
原理:Android系统中,各个系统服务分工明确,但核心功能需要协同完成(如启动Activity需要AMS管控组件、PMS校验组件、WMS显示窗口),AMS作为核心协调者,通过Binder机制与其他服务建立通信,统一调度各项功能,确保系统服务间的交互有序、高效。同时,服务间的双向反馈,能让AMS实时掌握系统状态(如电源、窗口、通知),动态调整组件和进程管理策略,保障系统稳定和用户体验。
在启动 Activity 时,AMS 如何与 WindowManagerService(WMS)协同工作?具体协作场景有哪些?
启动Activity的过程中,AMS与WMS是核心协同关系:AMS负责“组件生命周期管控、任务栈管理、进程调度”,WMS负责“窗口创建、界面渲染、窗口层级管理”,两者通过Binder机制实时通信,协同完成Activity从启动到显示的全流程,确保Activity能正常显示、切换,具体协同工作方式和核心协作场景如下:
一、协同工作的核心逻辑
启动Activity时,AMS先完成组件的合法性校验、进程创建(若需)、任务栈调整,再向WMS发送窗口创建和显示请求;WMS完成窗口创建、层级分配、界面渲染后,向AMS反馈窗口显示状态;AMS根据反馈,触发Activity的后续生命周期方法(如onResume),完成启动流程,形成“AMS管控→WMS显示→AMS确认”的协同闭环。
二、具体协同流程(以冷启动Activity为例)
AMS初始化启动参数:用户点击应用图标后,AMS接收启动请求,解析Intent中的Activity组件信息,通过PMS校验组件合法性,判断是否需要创建应用进程(若未启动),创建对应的任务栈,将Activity压入栈顶,完成Activity的初始化(创建ActivityRecord对象,记录Activity状态)。
AMS向WMS发送窗口创建请求:AMS完成组件初始化后,通过WMS的Binder代理对象,发送窗口创建请求,传递的参数包括:Activity的窗口属性(如大小、位置、透明度、窗口类型)、任务栈信息、Activity的进程信息(如进程ID)、窗口层级(前台Activity窗口层级最高)。
WMS创建窗口并分配资源:WMS接收请求后,执行以下操作:
① 创建WindowState对象(记录窗口状态),分配窗口ID,为窗口分配显示资源(如显存、绘制缓冲区);
② 根据AMS传递的窗口层级,将该窗口添加到窗口层级列表中(前台Activity窗口位于最顶层,避免被其他窗口遮挡);
③ 通知SurfaceFlinger(界面渲染服务),创建Surface(绘制表面),用于Activity界面的绘制。
WMS向AMS反馈窗口准备就绪:WMS完成窗口创建和Surface初始化后,通过Binder向AMS发送“窗口准备就绪”的反馈,告知AMS可以触发Activity的后续生命周期方法,让应用进程绘制界面。
AMS触发Activity后续生命周期:AMS接收反馈后,向应用进程发送onResume指令,应用进程收到指令后,通过SurfaceFlinger在WMS创建的Surface上绘制Activity界面(如布局渲染、控件绘制)。
WMS完成界面显示:应用进程绘制完成后,WMS通知SurfaceFlinger将绘制好的界面渲染到屏幕上,Activity正式显示在屏幕上;同时,WMS向AMS发送“界面显示完成”的反馈,AMS更新Activity的状态为“RESUMED”,完成整个启动流程。
三、核心协作场景
窗口创建与Activity生命周期联动:AMS控制Activity的生命周期(如onCreate、onResume),WMS同步创建和显示窗口,确保窗口状态与Activity状态一致——Activity处于onResume状态时,窗口显示;处于onPause状态时,窗口隐藏;处于onDestroy状态时,窗口销毁。例如,当Activity被暂停(如弹出弹窗),AMS通知WMS隐藏该Activity的窗口,弹窗窗口显示;当弹窗消失,AMS通知WMS显示该Activity的窗口,恢复界面。
多任务切换时的协同:用户切换应用(任务栈)时,AMS将目标任务栈设置为前台,原任务栈设置为后台,同时通知WMS:
① 隐藏原前台任务栈中所有Activity的窗口;
② 显示目标任务栈中栈顶Activity的窗口;
③ 调整窗口层级,确保目标窗口位于最顶层。WMS完成窗口切换和渲染后,向AMS反馈,AMS更新进程优先级,确保前台任务栈的进程能获得更多资源,切换流畅。
Activity配置变化时的协同:当Activity发生配置变化(如横竖屏切换),AMS会销毁原Activity,重新创建新的Activity,同时通知WMS:
① 销毁原Activity的窗口;
② 根据新的配置(如屏幕方向、分辨率),创建新的窗口,调整窗口大小和位置;
③ 重新分配Surface,让新Activity能正常绘制界面。WMS完成窗口重建后,反馈给AMS,AMS触发新Activity的生命周期方法,完成配置变化适配。
窗口层级与Activity优先级协同:AMS根据Activity的优先级(如前台Activity、可见Activity),向WMS传递窗口层级参数;WMS根据层级参数,调整窗口的显示顺序,确保高优先级Activity的窗口不被低优先级窗口遮挡。例如,前台Activity的窗口层级最高,弹窗窗口层级高于普通后台Activity窗口,系统对话框窗口层级高于所有应用窗口。
异常处理时的协同:当Activity启动失败(如资源不足),AMS通知WMS取消窗口创建,释放已分配的资源;当WMS出现异常(如窗口创建失败),WMS向AMS反馈,AMS终止Activity的启动流程,向应用进程发送异常提示,避免系统崩溃。
原理:Activity的显示依赖窗口,而窗口的创建和管理由WMS负责,组件的生命周期和任务栈由AMS负责,两者必须协同工作,才能确保Activity正常启动和显示。通过Binder机制,AMS与WMS实现实时通信,同步状态和参数,避免出现“Activity已启动但窗口未显示”“窗口已创建但Activity未初始化”等异常,同时协同完成多任务切换、配置变化等场景,保障用户体验。
AMS 如何响应系统广播事件?如何与系统事件(如屏幕方向变化、网络变化、电量变化等)进行交互?
AMS作为系统核心管控服务,需要实时响应系统广播事件和系统状态变化,根据事件类型调整组件和进程的管理策略,确保系统稳定和功能正常。其响应系统广播、与系统事件交互的核心逻辑是:通过“广播注册与接收”机制,监听系统广播和系统事件;通过“状态联动”机制,根据事件内容调整组件、进程状态,协同其他系统服务完成对应处理,具体细节如下:
一、AMS响应系统广播事件的方式
Android系统中的广播分为“系统广播”(如开机广播、网络变化广播)和“应用广播”,AMS主要响应系统广播,通过以下方式完成广播的接收和处理:
广播注册:AMS启动时,会通过BroadcastReceiver注册一系列系统广播的监听器,这些监听器运行在SystemServer进程中,专门监听系统级的广播事件(如ACTION_BOOT_COMPLETED、ACTION_NETWORK_STATE_CHANGED、ACTION_BATTERY_LOW等);同时,AMS也会接收其他系统服务(如PMS、PowerMS)发送的内部广播,同步系统状态变化。
广播接收与处理:当系统广播触发时(如设备开机、网络变化),BroadcastReceiver会接收广播,将广播事件传递给AMS;AMS根据广播的类型,执行对应的处理逻辑,调整组件和进程状态,同时通知相关应用进程(如发送广播给应用的BroadcastReceiver)。
广播优先级管控:AMS会根据广播的重要性,设置广播的处理优先级(系统广播优先级高于应用广播),确保重要的系统广播能被优先处理;同时,AMS会拦截非法广播(如未授权应用发送的系统广播),保障系统安全。
二、AMS与各类系统事件的交互细节
不同系统事件的交互逻辑不同,核心围绕“事件监听→状态调整→协同服务”展开,以下详细说明核心系统事件的交互流程:
屏幕方向变化(配置变化事件):
① 事件触发:用户旋转屏幕,导致屏幕方向变化,系统触发配置变化事件,由WMS检测并通知AMS;
② AMS处理:AMS接收事件后,判断当前前台Activity是否配置了android:configChanges属性(如orientation);
③ 若未配置:AMS会销毁当前Activity(触发onPause→onStop→onDestroy),重新创建新的Activity(onCreate→onStart→onResume),同时通知WMS调整窗口大小和位置,适配新的屏幕方向;
④ 若已配置:AMS不会销毁Activity,而是向应用进程发送onConfigurationChanged指令,让应用自行处理配置变化,同时通知WMS调整窗口参数,确保界面适配。
网络变化事件:
① 事件触发:设备网络状态变化(如从4G切换到WiFi、网络断开),由ConnectivityManagerService(网络管理服务)检测,发送系统广播(ACTION_NETWORK_STATE_CHANGED);
② AMS接收广播后,执行以下操作:
a. 通知所有正在运行的应用进程,同步网络状态变化(应用可根据网络状态调整行为,如网络断开时停止下载);
b. 调整后台任务的执行策略:网络断开时,暂停后台下载、同步等任务,避免无效资源消耗;网络恢复时,恢复后台任务;
c. 对于依赖网络的组件(如需要网络的Service),若网络断开,AMS会暂停该Service,网络恢复后重启。
电量变化事件:
① 事件触发:设备电量变化(如低电量、充电、电量充满),由PowerMS检测,发送系统广播(ACTION_BATTERY_LOW、ACTION_POWER_CONNECTED等);
② AMS接收广播后,执行以下操作:
a. 低电量时:启动低内存回收策略,优先回收后台进程、空进程,释放内存;限制后台组件的资源占用(如禁止后台Activity启动、暂停非必要的后台Service);通知应用进程低电量状态,让应用调整行为(如关闭高耗电功能);
b. 充电时:取消低电量限制,恢复后台任务的执行,提升后台进程的优先级,允许后台Activity启动;
c. 电量充满时:通知应用进程,停止充电相关的提示和操作。
屏幕亮灭事件:
① 事件触发:用户按电源键,导致屏幕亮灭,由PowerMS检测并通知AMS;
② AMS处理:
a. 屏幕熄灭时:通知WMS隐藏所有前台窗口;暂停前台Activity(触发onPause→onStop),降低前台进程的优先级;停止非必要的组件操作(如后台Service的耗时操作);
b. 屏幕点亮时:通知WMS显示前台任务栈的窗口;恢复前台Activity(触发onRestart→onStart→onResume),提升前台进程的优先级;恢复组件的正常运行。
开机完成事件:
① 事件触发:设备开机完成后,系统发送开机广播(ACTION_BOOT_COMPLETED);
② AMS接收广播后,执行以下操作:
a. 启动系统核心应用(如Launcher桌面应用),创建桌面Activity的任务栈,让桌面显示;
b. 恢复开机前的应用状态(如开机前正在运行的应用,若未被回收,恢复其任务栈和组件状态);
c. 启动系统常驻Service(如NotificationManagerService、ConnectivityManagerService),确保系统服务正常运行;
d. 通知所有应用进程开机完成,应用可执行开机启动相关操作(如启动常驻Service)。
三、交互的核心机制
AMS与系统事件交互的核心机制是“事件监听机制+状态联动机制”:① 事件监听机制:通过注册广播监听器,实时接收系统广播和其他系统服务的事件通知,确保能及时感知系统状态变化;② 状态联动机制:AMS根据事件内容,调整组件生命周期、进程优先级、任务栈状态,同时协同其他系统服务(如WMS、PowerMS、ConnectivityManagerService),完成对应的处理逻辑,确保系统状态与组件、进程状态同步。
原理:系统事件的变化会影响组件和进程的正常运行(如低电量时继续运行后台进程会消耗更多电量,网络断开时后台下载会失败),AMS作为核心管控者,必须实时响应这些事件,动态调整管理策略。通过广播机制接收事件,通过联动机制协调组件和服务,确保系统能适应不同的状态变化,保障稳定性和用户体验。
五、进程管理(核心高频)
AMS 在应用程序进程管理中扮演什么角色?如何创建和管理应用程序进程?
核心角色
AMS(ActivityManagerService)是 Android 系统进程管理的核心中枢,是系统服务(运行在 system_server 进程),全权负责所有应用进程的生命周期、调度、优先级管控、资源分配,是连接应用层与系统内核进程机制的桥梁。
核心职责
- 进程创建与销毁:统一发起应用进程的创建请求,管控进程的终止、回收;
- 四大组件生命周期调度:Activity/Service/Receiver/Provider 的启动、切换都会触发 AMS 进程调度;
- 进程优先级管理:动态计算进程优先级,决定系统资源分配顺序;
- 低内存管控:系统内存不足时,执行进程回收策略,保证系统流畅;
- 进程状态监控:实时监听进程的运行、挂起、死亡状态,维护进程注册表。
应用进程创建与管理流程
Android 应用进程并非应用自己创建,全部由 AMS 向 Zygote 进程发起请求创建:
- 触发条件:启动应用四大组件(如打开第一个 Activity、启动 Service)时,应用进程未启动,AMS 触发创建流程;
- Zygote 孵化进程:
- AMS 通过
Socket通信向 Zygote 进程发送创建请求; - Zygote 是所有应用进程的父进程,通过fork() 机制复制自身,创建新的应用进程;
- 新进程初始化
ActivityThread(应用主线程)、Application、Binder 线程池;
- AMS 通过
- 进程注册:进程创建完成后,
ActivityThread向 AMS 注册,AMS 将进程加入进程记录表(ProcessRecord) 统一管理; - 进程管理:
- AMS 为每个进程维护
ProcessRecord,记录进程名、PID、UID、优先级、组件状态; - 实时更新进程状态(前台/可见/后台),动态调整优先级;
- 监听进程死亡,清理资源并重启(如 Service 配置了自动重启)。
- AMS 为每个进程维护
AMS 如何判断是否需要为一个 Activity 创建新的进程?如何决定是否启动新进程运行 Activity?
AMS 完全依据AndroidManifest.xml 中配置的 android:process 属性判断,这是唯一核心依据。
1. 判断逻辑:是否需要新进程
- 默认情况:Activity 未配置
android:process,运行在应用默认进程(包名进程); - 自定义进程:Activity 配置了独立的
android:process(如:remote或com.xxx.process),AMS 判定需要独立进程; - 进程匹配校验: AMS 遍历已运行的进程列表,检查目标进程是否已存在:
- 已存在:直接复用进程,调度 Activity 运行;
- 不存在:触发新进程创建流程。
2. 启动新进程的决策规则
AMS 严格按照以下规则决定是否启动新进程:
- 进程名唯一性:目标
process对应的进程未运行,必须创建新进程; - 组件归属隔离:不同
process的组件必须运行在独立进程空间,互不干扰; - 系统限制校验:
- 系统进程数上限:达到上限时,AMS 会先回收低优先级进程,再创建新进程;
- 权限校验:系统应用/第三方应用的进程创建权限无差异,仅受配置控制;
- 特殊场景: 多应用共享
process(相同process+相同sharedUserId),AMS 会让它们运行在同一个进程中。
示例配置:
<!-- 运行在默认进程:com.example.app -->
<activity android:name=".MainActivity"/>
<!-- 运行在独立进程:com.example.app:remote -->
<activity
android:name=".RemoteActivity"
android:process=":remote"/>
AMS 如何处理进程的优先级?系统低内存时,如何决定应用的优先级和回收策略?
1. 进程优先级分级(从高到低)
AMS 基于进程中运行的组件类型、用户交互状态,将进程分为 5 个核心等级,优先级越高,越不容易被系统回收:
- 前台进程(Foreground Process) 优先级最高,用户正在交互的进程:持有前台 Activity、前台 Service、绑定前台服务的进程;
- 可见进程(Visible Process) 无焦点但用户可见:如 Activity 处于
onPause()(弹窗覆盖)、绑定可见服务的进程; - 服务进程(Service Process) 运行
startService()启动的后台服务(如音乐播放、文件下载),无界面但持续工作; - 后台进程(Background Process) 仅存在后台 Activity(已
onStop()),无服务无交互,如按 Home 键退出的应用; - 空进程(Empty Process) 无任何运行组件,仅为缓存机制保留,优先级最低。
2. 低内存回收策略
系统内存不足时,AMS 结合 LowMemoryKiller 内核机制执行回收,核心规则:
- 回收顺序:空进程 → 后台进程 → 服务进程 → 可见进程 → 前台进程(前台进程几乎不回收);
- 同优先级回收规则:
- 优先回收闲置时间最长的进程;
- 优先回收内存占用更大的进程;
- 回收阈值: 系统定义多级内存阈值,不同阈值对应回收不同优先级的进程,阈值由系统配置(
/sys/module/lowmemorykiller/parameters/minfree); - 进程复活机制: 被回收的进程,若有未处理的组件(如广播、Service),AMS 会在资源充足时重新创建进程并恢复组件。
AMS 如何处理进程的销毁?如何处理进程的挂起与恢复?
1. 进程销毁处理
AMS 销毁进程分为主动销毁和被动回收两种场景,流程标准化:
- 主动销毁(应用/系统主动调用)
- 应用调用
System.exit()、finish()所有 Activity 且无服务; - AMS 调用
killProcess()终止进程,清理ProcessRecord;
- 应用调用
- 被动回收(低内存触发)
- AMS 通知
LowMemoryKiller内核模块回收进程; - 进程被强制终止,无任何回调(
onDestroy()不会执行);
- AMS 通知
- 销毁后处理: AMS 从进程注册表中移除该进程,释放 Binder 引用、组件资源,若配置了重启机制,则重新孵化进程。
2. 进程挂起与恢复
Android 5.0 后引入进程冻结(挂起) 机制,AMS 负责全程管控:
- 挂起条件 后台进程无服务、无广播、无任务执行,且闲置一段时间,AMS 判定为可挂起;
- 挂起流程
- AMS 向内核发送冻结指令,暂停进程的 CPU 调度、线程执行;
- 进程保留内存空间,但不消耗 CPU 资源,降低功耗;
- 恢复流程
- 触发条件:用户切换回应用、启动组件、接收广播;
- AMS 发送解冻指令,恢复进程 CPU 调度,唤醒主线程;
- 应用恢复运行状态,Activity 执行
onRestart()/onResume()。
核心特性:挂起不是销毁,进程仍驻留内存,恢复速度远快于重启。
AMS 如何管理 Android 中的进程和线程?如何控制多进程的启动和调度?如何实现进程间通信的高效调度?
1. 进程与线程管理
- 进程管理
- 以
ProcessRecord为核心单元,统一管理所有应用进程; - 管控进程生命周期:创建 → 运行 → 挂起 → 销毁;
- 隔离进程空间:每个进程拥有独立的虚拟机、内存空间、资源文件,互不干扰。
- 以
- 线程管理
- 每个应用进程有唯一主线程(UI 线程),由
ActivityThread维护,AMS 调度组件必须在主线程执行; - 管理 Binder 线程池:用于进程间通信,AMS 分配线程数,避免线程泄漏;
- 禁止跨进程线程共享,线程仅归属自身进程。
- 每个应用进程有唯一主线程(UI 线程),由
2. 多进程启动与调度控制
- 启动控制
- 依据
android:process配置,AMS 串行/并行孵化多进程; - 限制进程数量:系统设定最大进程数,防止内存溢出;
- 权限管控:系统进程拥有更高权限,第三方应用进程受沙箱限制。
- 依据
- 调度控制
- CPU 调度:AMS 结合进程优先级,为高优先级进程分配更多 CPU 时间片;
- 组件调度:跨进程启动组件时,AMS 负责路由、权限校验、进程唤醒;
- 资源调度:内存、IO 资源优先分配给前台/可见进程。
3. 进程间通信(IPC)高效调度
AMS 是 IPC 调度的核心,基于 Binder 机制 实现高效通信:
- Binder 驱动:内核层实现进程间内存共享,比传统 Socket 更快、开销更低;
- AMS 调度流程:
- 客户端进程发起 IPC 请求(如启动远程 Service);
- AMS 接收请求,校验权限、唤醒目标进程;
- AMS 通过 Binder 驱动转发数据,调度目标进程执行逻辑;
- 执行结果通过 Binder 回传客户端;
- 优化策略:
- 复用 Binder 线程池,减少线程创建开销;
- 批量处理 IPC 请求,降低通信频次;
- 后台进程 IPC 限流,保证前台进程流畅性。
如何利用 AMS 进行后台进程的管理与调度?核心管理策略有哪些?
AMS 对后台进程的管理核心目标:降低内存/CPU 消耗、节省功耗、保证前台应用流畅。
1. 核心管理策略
- 后台进程优先级降级 应用进入后台后,AMS 立即将其优先级从前台/可见降级为后台进程,减少资源分配。
- 后台进程冻结(挂起) 闲置后台进程被 AMS 冻结,暂停 CPU 调度,仅保留内存,大幅降低功耗。
- 后台进程数量限制 系统设定后台进程上限,超出部分直接回收,避免内存占用过高。
- 后台任务限制
- 禁止后台进程频繁启动组件、占用 CPU;
- 后台 Service 受严格限制(Android 8.0 后禁止后台启动 Service)。
- 低内存主动回收 内存紧张时,AMS 优先回收后台闲置进程,保证前台应用可用内存。
- 白名单机制 音乐、导航等应用可加入后台白名单,不被冻结/回收,保证持续运行。
2. AMS 调度方式
- 动态调整:根据后台进程运行状态,实时调整优先级和冻结状态;
- 批量回收:一次性回收多个无用后台进程,减少系统抖动;
- 唤醒限制:严格限制后台进程被频繁唤醒,降低电量消耗。
AMS 如何处理应用切换和进程调度?如何保证切换过程的流畅性?
1. 应用切换与进程调度流程
用户切换应用(如按 Home、最近任务)时,AMS 执行完整调度流程:
- 旧应用进程调度
- 将前台 Activity 执行
onPause()→onStop(); - 进程优先级从前台进程降级为后台进程;
- 闲置后执行挂起,释放 CPU 资源。
- 将前台 Activity 执行
- 新应用进程调度
- 检查目标进程是否存在:不存在则孵化,存在则直接唤醒;
- 提升新进程优先级为前台进程,分配最高 CPU/内存资源;
- 调度目标 Activity 执行
onRestart()→onStart()→onResume()。
- 进程间切换 AMS 通过 Binder 完成跨进程通信,协调新旧进程的状态切换,保证无缝衔接。
2. 保证切换流畅性的核心机制
- 优先级预提升 切换前提前将目标应用进程优先级提升,优先分配系统资源,避免卡顿。
- 内存预分配 为目标进程预留足够内存,防止切换时因内存不足触发 GC 或进程回收。
- 挂起/解冻优化 旧应用快速挂起,新应用快速解冻,减少线程调度延迟。
- UI 渲染优先级 前台进程的 UI 渲染线程拥有最高调度优先级,保证界面立即响应。
- 进程缓存机制 后台进程保留空进程缓存,切换时无需重新创建进程,大幅提升启动速度。
- 系统资源限流 切换期间暂停非关键任务(如后台同步、日志上传),集中资源服务应用切换。
六、后台管控、保活与权限限制
AMS 如何决定一个应用是否可以在后台继续运行?核心判断因素有哪些?
AMS 并非允许所有应用无限制后台运行,而是通过组件状态、权限、系统版本限制、用户操作四大维度综合判定,核心是区分“允许后台”和“禁止后台”的临界条件。
核心判断因素
进程内组件存活状态
- 存在前台 Service(带通知栏):允许后台持续运行;
- 存在绑定服务(被其他进程/系统依赖):允许后台运行;
- 存在未完成的广播/工作任务:短时间允许后台执行;
- 无任何活跃组件(仅空进程):判定为可回收/禁止后台。
Android 版本后台限制规则
- Android 8.0+:禁止后台启动普通 Service,仅允许前台 Service/WorkManager;
- Android 10+:新增后台位置权限限制、后台启动 Activity 限制;
- Android 12+:强化后台网络、CPU 资源限流,严格管控后台唤醒。
应用权限与白名单
- 拥有后台运行权限(用户手动开启):不受严格限制;
- 系统白名单(如音乐、导航、闹钟):豁免后台管控;
- 无权限/被用户手动限制:直接禁止后台运行。
系统资源与用户行为
- 低内存场景:强制终止后台进程;
- 用户手动「强制停止」/「禁止后台活动」:永久禁止后台运行;
- 应用长时间后台闲置:自动冻结/回收。
判定结论
- 允许后台:持有前台服务、绑定服务、系统白名单、用户授权后台运行;
- 禁止后台:无活跃组件、无权限、低内存、用户限制、版本合规性拦截。
2. AMS 中的进程保活机制是如何工作的?应用如何与该机制协作实现保活?
AMS 本身不提供“恶意保活”,官方设计的是合规保活机制,目的是保证核心功能正常运行,而非让应用无限后台存活。
1. AMS 官方保活机制原理
- 优先级提升保活 AMS 会为持有前台 Service、可见界面、系统依赖组件的进程提升优先级,避免被 LowMemoryKiller 回收。
- 组件依赖保活 应用组件被其他进程绑定(如 ContentProvider、Service 被系统调用),AMS 会保证进程存活。
- 系统回调保活 广播(如开机、网络变化)、WorkManager 任务触发时,AMS 会临时唤醒进程并允许短时间后台执行。
- 进程重启机制 配置了
START_STICKY的 Service,被系统回收后,AMS 会在资源充足时自动重启进程和服务。
2. 应用与 AMS 协作的合规保活方式
- 使用前台 Service 申请通知权限,启动前台服务,AMS 会将进程标记为前台优先级,几乎不回收。
- 使用 WorkManager 后台任务 交给系统调度,AMS 保证任务在合规范围内执行,无需应用自己保活。
- 申请后台运行白名单 引导用户开启「后台运行权限」,绕过系统后台限制。
- 利用系统广播/系统服务依赖 注册系统广播(如耳机插拔、电量变化),被动唤醒进程。
3. 非官方保活(已失效)
1 像素 Activity、双进程互相拉起、JobScheduler 暴力唤醒等,在 Android 9.0+ 已被 AMS 全面封杀,无法生效。
3. 如何通过 AMS 配置应用的后台进程限制?系统层面和应用层面分别有哪些配置方式?
AMS 提供系统层全局配置和应用层清单配置两种方式,管控后台进程数量与行为。
1. 应用层配置(AndroidManifest.xml)
android:process 自定义进程名,控制多进程数量,避免无意义进程占用内存。
android:maxProcesses(API 16+) 限制应用最大进程数,防止多进程滥用。
<application android:maxProcesses="3" /> <!-- 最多3个进程 -->android:stopWithTask 任务栈销毁时,直接终止进程,禁止后台残留:
<activity android:stopWithTask="true" />service 配置 禁止后台服务自动重启:
<service android:stopWithTask="true" />
2. 系统层配置(厂商/ROM 控制)
后台进程阈值配置 系统配置文件
/system/build.prop设定后台进程上限:ro.sys.fw.bg_apps_limit=20LowMemoryKiller 回收阈值 调整内存阈值,控制何时开始回收后台进程:
/sys/module/lowmemorykiller/parameters/minfree厂商后台管理策略 小米/华为/OV 等通过系统设置,对应用执行「智能限制后台」「后台冻结」「锁屏清理」。
adb 命令强制限制
adb shell am set-debug-app -w --stop-on-idle com.example.app
3. AMS 执行逻辑
配置生效后,AMS 会实时统计进程数量,超出限制则优先回收优先级最低的后台进程,保证系统资源。
4. AMS 如何处理后台任务的执行和管理?如何控制后台任务的资源占用?
AMS 对后台任务的核心策略:允许执行、严格限流、超时回收、资源隔离,杜绝后台任务抢占前台资源。
1. 后台任务执行管理流程
- 任务接收 应用通过 WorkManager、JobScheduler、广播发起后台任务,AMS 统一接收并登记。
- 合规校验 检查应用是否有后台权限、是否在白名单、是否触发系统限制。
- 调度执行
- 高优先级任务(如下载、音乐):立即执行;
- 普通任务:批量调度,避免并发占用资源;
- 违规任务(后台启动 Activity/Service):直接拦截。
- 超时管控 后台任务执行超时(广播 10s、服务 1min),AMS 强制终止,防止资源占用。
- 任务完成 释放资源,将进程降级为后台闲置状态,等待冻结/回收。
2. 后台任务资源控制手段
- CPU 限流 后台进程 CPU 时间片仅为前台进程的 1/10 以下,避免卡顿。
- 网络限流 后台进程网络带宽受限,禁止大流量后台传输。
- 唤醒锁限制 非白名单应用无法持有长期唤醒锁,禁止后台持续唤醒 CPU。
- 批量执行 合并多个后台任务统一执行,减少频繁唤醒带来的功耗。
- 后台冻结 任务执行完成后,立即冻结进程,暂停所有线程执行。
- 低内存回收 内存不足时,直接终止后台任务与进程。
七、任务栈与 Activity 栈管理
什么是任务栈(Task Stack)?任务栈的主要作用是什么?
定义
任务栈(Task) 是 AMS 中用于管理一组相关 Activity 的后进先出(LIFO)栈结构,一个应用可以有多个任务栈,多个应用也可以共用一个任务栈。 简单理解:任务栈 = 用户一次交互的“任务记录”,比如打开微信→聊天页→详情页,这一组页面就是一个任务栈。
核心作用
- 管理页面回退 按返回键时,按照栈顺序依次回退,保证操作逻辑符合用户直觉。
- 区分多任务场景 最近任务列表中,每一个条目对应一个任务栈,方便用户切换不同任务。
- 维护应用交互状态 记录用户打开的页面顺序,应用切换/重启后恢复交互流程。
- 控制页面启动模式 配合 launchMode 实现单实例、复用、清空栈等逻辑。
AMS 如何管理任务栈?具体有哪些操作(如创建、切换、销毁)?
AMS 以 TaskRecord 为单元管理任务栈,所有操作都由 AMS 统一调度,应用无权直接修改。
核心操作
任务栈创建
- 启动第一个 Activity 时,AMS 自动创建新任务栈;
- 配置
launchMode="singleTask"/"singleInstance"时,创建独立任务栈; - 跨应用启动 Activity,可共用或新建任务栈。
任务栈切换
- 用户点击最近任务、桌面图标、跨应用跳转时触发;
- AMS 将目标任务栈移至前台栈顶,原栈移至后台;
- 同步切换进程优先级,前台栈对应进程提升为前台优先级。
任务栈置顶/调整 系统可将指定任务栈移到前台,如来电界面强制置顶。
任务栈销毁
- 用户清空最近任务、应用所有 Activity 关闭;
- 系统低内存回收后台任务栈;
- 配置
finishOnTaskLaunch时,重启应用销毁旧栈。
任务栈清空 使用
FLAG_ACTIVITY_CLEAR_TASK清空栈内所有 Activity,重建新栈。
AMS 如何通过任务栈控制应用的跳转与返回操作?核心逻辑是什么?
1. 页面跳转控制逻辑
- AMS 根据
launchMode和Intent Flag判断目标 Activity 所在任务栈; - 若目标 Activity 已存在于栈中:
standard:创建新实例入栈;singleTop:复用栈顶实例;singleTask:清空上方 Activity,复用实例;singleInstance:独立栈中唯一实例,直接切换栈。
- 若不存在:创建新实例并入对应任务栈。
2. 返回键控制逻辑
- 用户按下返回键,AMS 检查当前任务栈:
- 栈内有多个 Activity:出栈销毁当前页面,显示上一个;
- 栈内只剩根 Activity:回退到桌面,任务栈进入后台;
- 任务栈为空:销毁任务栈。
- 跨任务栈返回: 按返回键只会在当前任务栈内回退,不会跨栈跳转。
核心逻辑
任务栈决定跳转目标,回退遵循“后进先出”,所有调度由 AMS 统一计算,应用仅通过配置参与规则。
AMS 如何管理 Activity 栈的回退机制?与任务栈回退有何区别?
1. Activity 栈回退机制
Activity 栈是任务栈内部的页面栈,回退规则:
- 标准回退:
onPause → onStop → onDestroy,页面出栈; FLAG_ACTIVITY_CLEAR_TOP:清空目标页面上方所有页面;onBackPressed():应用可重写返回逻辑,但最终仍由 AMS 执行出栈。
2. 与任务栈回退的核心区别
| 维度 | Activity 栈回退 | 任务栈回退 |
|---|---|---|
| 范围 | 单个任务栈内部 | 整个任务栈的生命周期 |
| 对象 | 单个 Activity 页面 | 一组 Activity 集合 |
| 效果 | 关闭当前页面,显示上一页 | 任务栈退至后台/销毁 |
| 用户感知 | 页面切换 | 应用切换/退出到桌面 |
| 调度者 | AMS 内部栈管理 | AMS 任务调度中心 |
一句话总结:Activity 栈回退是页面内退,任务栈回退是任务退出/切换。
AMS 如何实现多任务切换时的状态保持?具体通过哪些方式实现?
多任务切换(Home 键/最近任务)时,AMS 保证应用恢复后状态不变,核心机制:
生命周期状态保存 页面退至后台时执行
onSaveInstanceState(),AMS 保存页面状态(如输入框内容、列表位置)。任务栈完整保留 后台任务栈不会被清空,所有 Activity 顺序、实例完整保留。
进程挂起而非销毁 AMS 冻结进程,不释放内存,恢复时直接解冻,无需重新加载。
Activity 状态记录 AMS 为每个 Activity 记录状态(启动模式、参数、Intent),切换回来直接恢复。
系统级状态缓存 即使进程被回收,AMS 仍保留任务栈结构,重启时重新创建 Activity 并恢复状态。
AMS 如何处理任务栈中 Activity 的排序与优先级?如何管理任务栈的切换?
1. Activity 排序规则
- 严格遵循后进先出,新启动 Activity 永远在栈顶;
- 复用模式(singleTop/singleTask)会调整顺序,清空上方页面;
- 跨应用启动可将 Activity 加入当前栈或新建栈。
2. 任务栈优先级
- 前台任务栈:最高优先级,对应进程为前台进程;
- 可见后台栈:如弹窗覆盖,优先级次之;
- 完全后台栈:优先级最低,可被回收。
3. 任务栈切换管理
- 用户触发:点击桌面图标、最近任务、返回键;
- 系统触发:来电、闹钟、系统弹窗;
- AMS 调度:
- 切换前台栈;
- 调整对应进程优先级;
- 执行 Activity 生命周期(onPause/onResume);
- 保证界面无缝切换。
在 Android 系统中,AMS 如何管理后台 Activity 的生命周期?核心管理策略是什么?
后台 Activity 生命周期流程
前台 → 后台:onPause → onSaveInstanceState → onStop 后台 → 前台:onRestart → onStart → onResume
AMS 核心管理策略
- 不主动销毁后台 Activity 只要内存充足,保留所有后台页面实例。
- 低内存回收 内存不足时,按优先级回收后台 Activity 及其所在进程。
- 状态强制保存 进入后台必须执行
onSaveInstanceState(),保证恢复后数据不丢失。 - 生命周期严格串行 AMS 强制按顺序执行回调,不允许乱序。
- 禁止后台 UI 操作 后台 Activity 无法更新 UI、无法弹窗,防止异常。
AMS 如何处理多任务和单任务模式?两种模式下的管理逻辑有何区别?
1. 单任务模式(SingleTask/SingleInstance)
- 特征:一个任务栈只有一个/少量 Activity,全局唯一实例;
- AMS 管理:
- 独立任务栈,不与其他页面混用;
- 每次启动都复用实例,清空上方页面;
- 返回键直接退出任务栈。
- 适用:桌面、拨号、主页面。
2. 多任务模式(Standard/SingleTop)
- 特征:一个任务栈包含多个 Activity,支持多实例;
- AMS 管理:
- 允许创建多个实例,按顺序入栈;
- 支持连续跳转和连续回退;
- 可同时存在多个任务栈。
- 适用:普通应用页面、浏览器、社交应用。
核心区别
| 维度 | 单任务模式 | 多任务模式 |
|---|---|---|
| 实例数量 | 全局唯一 | 可多实例 |
| 任务栈 | 独立独占 | 共享/多栈 |
| 启动逻辑 | 复用实例 | 创建新实例 |
| 返回逻辑 | 直接退出任务 | 逐级回退 |
| 内存占用 | 低 | 较高 |
八、Activity 生命周期管理
AMS 如何管理应用的生命周期?核心管理逻辑是什么?
核心定位
AMS 是应用与 Activity 生命周期的唯一调度者,应用自身无法主动控制生命周期全局流程,只能通过回调响应 AMS 指令。 应用生命周期分为进程生命周期和组件生命周期,AMS 统一管控两者的联动关系。
核心管理逻辑
- 中心化调度 所有生命周期事件(启动、暂停、恢复、销毁)均由 AMS 决策并下发,应用进程(ActivityThread)被动执行。
- 状态机驱动 AMS 为每个 Activity 维护生命周期状态机(初始化、已创建、已开始、已恢复、已暂停、已停止、已销毁),严格控制状态流转顺序,不允许跳步/乱序。
- 进程优先级绑定 生命周期状态直接决定进程优先级:
- 前台/Resume 状态 = 最高优先级
- 暂停/Pause 状态 = 可见优先级
- 停止/Stop 状态 = 后台优先级
- 系统事件触发 生命周期由系统事件驱动:用户操作、应用切换、配置变化、内存回收、系统销毁。
- 安全与隔离 AMS 校验启动权限、进程合法性、栈规则,确保生命周期在安全规则内执行。
完整生命周期管控链路
用户操作/系统事件 → AMS 决策 → Binder 通信 → ActivityThread 调度 → 执行生命周期回调 → 反馈状态给 AMS
AMS 如何管理 Activity 生命周期中的各个状态(onCreate、onStart、onResume 等)?
AMS 以精确状态机管理生命周期,每个方法都对应 AMS 内部一个固定状态,严格按顺序执行。
生命周期全流程 + AMS 管控逻辑
- onCreate()
- AMS 状态:
INITIALIZING → CREATED - 逻辑:创建 Activity 实例、加载布局、完成初始化;仅执行一次。
- onStart()
- AMS 状态:
CREATED → STARTED - 逻辑:Activity 变为用户可见,但未获取焦点。
- onResume()
- AMS 状态:
STARTED → RESUMED - 逻辑:Activity 获取焦点,可交互,成为前台 Activity。
- onPause()
- AMS 状态:
RESUMED → PAUSED - 逻辑:失去焦点,系统要求快速执行;AMS 会等待该方法完成。
- onStop()
- AMS 状态:
PAUSED → STOPPED - 逻辑:完全不可见,进入后台。
- onDestroy()
- AMS 状态:
STOPPED → DESTROYED - 逻辑:销毁实例,释放资源;AMS 清理 Activity 记录。
- 异常生命周期
- onSaveInstanceState():系统销毁前保存状态
- onRestoreInstanceState():重建后恢复状态
AMS 强制约束
- 必须按顺序执行,不允许跳过任何一步;
- 同一时刻一个 Activity 只能处于一种状态;
- 跨进程生命周期调度必须通过 Binder 同步执行。
AMS 如何处理 Activity 的启动、停止和恢复?如何处理配置变化(横竖屏切换)?
1. 启动流程(AMS 核心调度)
- AMS 接收启动请求 → 校验权限、栈规则、进程状态;
- 进程不存在 → 孵化进程;
- 创建任务栈/压入栈顶 → 切换进程优先级为前台;
- 依次调度:
onCreate → onStart → onResume。
2. 停止流程
- 切换应用/打开新页面 → AMS 指令当前页面暂停;
- 执行
onPause→ 新页面启动完成; - 执行
onStop→ 进程优先级降级为后台。
3. 恢复流程
- 从后台切回 → AMS 提升进程优先级;
- 调度执行
onRestart → onStart → onResume; - 重新成为前台页面。
4. 配置变化(横竖屏、分辨率、语言切换)
AMS 默认策略:销毁并重建 Activity
- 触发配置变化;
- AMS 调用
onSaveInstanceState()保存状态; - 执行
onPause → onStop → onDestroy; - 创建新的 Activity 实例;
- 调用
onRestoreInstanceState()恢复数据; - 重建完成。
避免重建方式 在清单中配置: android:configChanges="orientation|screenSize" AMS 不会重建,只会回调 onConfigurationChanged()。
在 AMS 中,Activity 的暂停和恢复过程是怎样的?如何处理 Activity 的 onSaveInstanceState 和 onRestoreInstanceState?
1. 暂停过程(Pause)
- 新 Activity 启动请求 → AMS 优先暂停当前前台 Activity;
- AMS 跨进程通知应用主线程执行
onPause(); - 必须等 onPause 执行完毕,AMS 才会启动下一个页面;
- 状态变为 PAUSED,进程变为可见优先级。
2. 恢复过程(Resume)
- 回到原 Activity → AMS 调度恢复;
- 若只是暂停:直接执行
onResume(); - 若已停止:执行
onRestart → onStart → onResume; - 状态变为 RESUMED,进程恢复前台优先级。
3. 状态保存与恢复机制
- onSaveInstanceState()
- AMS 主动触发时机:系统配置变化、系统低内存回收、后台被回收;
- 目的:在被系统销毁前保存状态;
- 工作:AMS 提供 Bundle,由应用存入数据;
- 时机:
onPause 之后,onStop 之前。
- onRestoreInstanceState()
- AMS 触发时机:Activity 被系统销毁后重建;
- 作用:从 AMS 保存的 Bundle 中恢复状态;
- 时机:
onStart 之后,onResume 之前。
核心结论 只有系统异常销毁才会触发这两个方法; 用户主动返回销毁(finish)不会触发。
如何通过 AMS 实现 Activity 销毁与资源释放?具体流程是什么?
销毁触发场景
- 用户主动返回(finish())
- 系统配置变化重建
- 低内存回收
- 任务栈清空
- 系统强制销毁
AMS 销毁流程
- AMS 下发销毁指令;
- 执行生命周期:
onPause → onStop → onDestroy; - 应用在
onDestroy中释放资源(注销广播、释放线程、取消网络); - AMS 移除 ActivityRecord 记录、清理栈;
- 若栈空/无组件,AMS 可回收进程。
关键注意点
- 低内存销毁不保证 onDestroy 执行;
- 必须在
onPause/onStop中释放关键资源; - 后台 Activity 优先级最低,最容易被销毁。
如何实现 Activity 生命周期的优化,减少内存消耗?AMS 在其中起到什么作用?
1. 应用层优化
- 避免在 onCreate 做耗时操作
- onPause 不执行耗时操作(阻塞页面切换)
- onStop 释放非关键资源
- onDestroy 释放大型对象、注销监听
- 状态懒加载、避免重复创建
- 配置变化避免重建
2. AMS 在优化中的核心作用
- 生命周期时序管控,避免耗时阻塞;
- 低内存提前通知,让应用释放缓存;
- 自动管理进程优先级,降低后台消耗;
- 自动保存/恢复状态,减少崩溃丢失数据;
- 限制后台 Activity 数量,避免内存溢出;
- 调度 GC 时机,降低前台卡顿概率。
Activity 的生命周期变化是如何被 AMS 监听和管理的?核心通信机制是什么?
核心通信机制:Binder IPC
- AMS 运行在
system_server系统进程 - 应用运行在独立应用进程
- 生命周期指令 = 跨进程通信
完整通信流程
- AMS 通过
IApplicationToken标识目标 Activity; - AMS → Binder →
ApplicationThread(应用端 Binder 服务); ApplicationThread转交给ActivityThread;ActivityThread切换到主线程执行生命周期;- 执行完毕 → Binder 反馈状态给 AMS;
- AMS 更新状态机。
AMS 监听方式
- 维护所有 Activity 生命周期状态表;
- 监控超时(如 onPause 超时会被系统杀死);
- 监控生命周期异常;
- 监控页面启动/切换/退出。
如何利用 AMS 来管理 Activity 的销毁策略?核心判断依据是什么?
AMS 拥有最高销毁决策权,应用只能配置规则,不能完全控制。
核心判断依据
- 进程优先级 后台进程优先级越低,所在 Activity 越容易被销毁。
- 页面可见性 完全不可见(onStop)的 Activity 优先销毁。
- 系统内存状态 内存越低,销毁范围越大、越激进。
- 任务栈层级 栈底 Activity 最后销毁;栈顶后台 Activity 优先销毁。
- 配置变化 横竖屏等配置变化默认销毁重建。
- 用户操作 返回键、划掉最近任务直接销毁。
- 清单配置
noHistory="true":离开即销毁finishOnTaskLaunch="true":重启任务时销毁configChanges:避免配置变化销毁
AMS 销毁策略
- 正常情况:不主动销毁,保留实例提升切换速度
- 低内存:按“后台 → 服务 → 可见”顺序销毁
- 任务终止:清空栈并销毁所有 Activity
- 系统异常:销毁并保存状态,可恢复
九、Activity 启动参数、启动模式、Intent 解析
AMS 如何管理 Activity 的启动参数(如 Intent)?在 Activity 启动时,如何解析 Intent 信息?
1. Intent 核心作用
Intent 是 Activity 启动的参数载体 + 跳转指令,包含:
- 目标组件(包名、类名)
- Action、Category
- 数据(Data)
- 标记(Flags)
- 额外数据(Extras)
- 启动权限、调用者身份
2. AMS 对 Intent 的管理
- 统一接收 所有启动请求统一发给 AMS,应用不能直接启动 Activity。
- 合法性校验
- 权限检查
- 组件是否存在
- 是否为导出组件
- 是否允许外部启动
- Intent 解析(匹配目标) 分为显式 Intent 和隐式 Intent。
显式:直接指定包名+类名 → AMS 直接匹配目标。 隐式:Action/Category/Data → AMS 查询PackageManagerService匹配组件。
- 参数保存 AMS 将 Intent 完整保存到 ActivityRecord,生命周期全程携带。
3. 解析流程
- 应用发起 startActivity;
- 到达 AMS 的
startActivity方法; - 解析 Intent 类型;
- 显式:直接定位目标;
- 隐式:PMS 匹配清单文件中的 intent-filter;
- 多匹配项:弹出选择器;
- 无匹配:抛出 ActivityNotFoundException。
AMS 如何调度 Activity 的启动顺序和优先级?如何保证 Activity 启动的顺序性?
1. 启动优先级规则
- 前台进程优先级最高 前台应用启动 Activity 优先调度。
- 系统界面 > 第三方应用 电话、闹钟、系统弹窗优先。
- 任务栈顶 > 栈内其他页面
- Intent Flag 可调整优先级 如
FLAG_ACTIVITY_REORDER_TO_FRONT。
2. 启动顺序保证
AMS 采用严格串行化调度:
- 必须等前一个
onPause执行完成; - 再启动新的 Activity;
- 新页面
onResume完成后; - 旧页面才执行
onStop。
核心保证
- 同一任务栈内,启动顺序严格遵循调用顺序;
- 跨进程启动通过 Binder 同步有序执行;
- AMS 使用消息队列保证串行,不并发启动。
AMS 如何处理不同来源的 Activity 启动请求?如何处理不同的启动模式(standard、singleTop、singleTask、singleInstance)?
启动模式决定 Activity 的实例创建规则、任务栈归属、复用逻辑。 AMS 完全控制所有模式的调度逻辑。
1. standard(标准模式)
- 规则:每次启动都创建新实例
- 栈:并入当前任务栈
- 复用:不复用
- 场景:普通页面 AMS 逻辑:直接创建新实例压入栈顶。
2. singleTop(栈顶复用)
- 规则:若目标在栈顶,复用不重建;否则创建新实例
- 栈:当前任务栈
- 回调:onNewIntent() AMS 逻辑:检查栈顶 → 是则复用,否则新建。
3. singleTask(栈内复用)
- 规则:全局单实例,清空上方所有页面
- 栈:独立任务栈(或指定栈)
- 回调:onNewIntent() AMS 核心逻辑:
- 查找实例是否存在
- 存在 → 清空其上所有 Activity
- 将其移到栈顶
- 调用 onNewIntent
4. singleInstance(单实例独占栈)
- 规则:全局唯一,独占一个任务栈
- 特点:该栈只有这一个页面
- 场景:通话界面、闹钟、地图导航 AMS 逻辑:创建独立任务栈,只存放此页面,全局复用。
AMS 统一调度流程
- 获取启动模式
- 检查任务栈
- 检查实例是否存在
- 决定:新建 / 复用 / 清栈 / 切换栈
- 执行生命周期
十、Activity 完整启动流程(超级重点)
详细描述 Activity 从点击图标到在屏幕上显示的整个过程中,AMS 的具体操作?
点击桌面图标本质是启动 Launcher 中对应的快捷方式 Activity,整个流程由 system_server 进程中的 AMS 中心化控制,应用进程只负责被动执行。
阶段 1:Launcher 发起启动请求
- 用户点击桌面图标;
- Launcher 调用
startActivity(),通过 Binder 进入 AMS; - 携带 Intent(Action=MAIN,Category=LAUNCHER)与调用者 PID/UID。
阶段 2:AMS 做安全与合法性校验
- AMS 校验调用者权限,检查是否允许启动该 Activity;
- 通过 PMS 解析目标应用清单,确认目标 Activity 存在、 exported 状态合法;
- 检查是否有相应的 intent-filter 匹配;
- 检查应用是否被禁用、处于强制停止状态。
阶段 3:判断应用进程是否存在
AMS 遍历自身维护的 ProcessRecord 列表:
- 进程不存在:进入冷启动流程;
- 进程存在:进入热启动流程。
阶段 4:创建应用进程(冷启动)
- AMS 通过 Socket 向 Zygote 进程发送
fork()请求; - Zygote 孵化新应用进程,初始化
ActivityThread、Binder 线程池; - 新进程通过 Binder 向 AMS 注册,AMS 创建
ProcessRecord; - AMS 通知进程创建
Application,执行attach()和onCreate()。
阶段 5:创建/复用任务栈与 ActivityRecord
- AMS 为目标 Activity 创建
ActivityRecord; - 根据启动模式与任务栈规则,决定新建任务栈或加入已有栈;
- 将任务栈移至前台,标记为当前聚焦栈。
阶段 6:调度生命周期(核心)
- AMS 跨进程通知应用主线程执行:
onCreate → onStart → onResume; - AMS 等待
onResume执行完成; - 通知 WMS(WindowManagerService)创建窗口、测量、布局、绘制;
- 画面提交 SurfaceFlinger 渲染上屏。
阶段 7:完成显示与状态更新
- Activity 完全可见可交互;
- AMS 将该进程标记为前台进程;
- 更新任务栈顺序,更新最近任务列表。
Activity 的启动过程涉及哪些关键方法?AMS 在这些方法调用中扮演什么角色?
应用进程侧关键方法
- Activity.onCreate()
- AMS 角色:下发创建指令,等待创建完成,记录状态为 CREATED。
- Activity.onStart()
- AMS 角色:标记为可见状态,进程优先级提升。
- Activity.onResume()
- AMS 角色:核心同步点,必须等 resume 完成才认为页面启动成功。
- Activity.onPause()
- AMS 角色:启动新 Activity 前必须等待旧页面执行完毕。
- ActivityThread.handleLaunchActivity()
- AMS 角色:通知应用进程实例化 Activity 并触发生命周期。
- ActivityThread.handleResumeActivity()
- AMS 角色:同步阻塞点,保证页面真正就绪。
AMS 内部核心方法
- ActivityManagerService.startActivity()
- 入口方法,接收所有启动请求。
- ActivityStackSupervisor.realStartActivityLocked()
- 真正执行启动调度。
- ActivityStack.resumeTopActivityInnerLocked()
- 恢复栈顶 Activity。
- ApplicationThread.scheduleLaunchActivity()
- AMS 跨进程调用应用端,触发页面创建。
- AMS.startProcessLocked()
- 启动应用进程。
AMS 统一角色
- 决策方:决定是否启动、何时启动、在哪个进程与栈启动;
- 调度方:按顺序下发生命周期;
- 同步方:保证生命周期串行不混乱;
- 状态维护方:维护全局 Activity 状态机。
在 AMS 中,Activity 的启动流程是怎样的?核心步骤有哪些?
步骤 1:启动请求接收与过滤
- 来自 startActivity、Intent、Launcher、系统、第三方应用;
- AMS 统一收口,不允许应用直接跨进程启动。
步骤 2:权限与组件校验
- 权限检查;
- 组件存在性检查;
- 应用状态检查(未被冻结、未被强制停止)。
步骤 3:进程判断与创建
- 目标进程不存在 → AMS 主动创建进程;
- 进程创建完成后绑定 Application。
步骤 4:任务栈与启动模式处理
- 查找目标 Activity 是否存在实例;
- 根据 standard / singleTop / singleTask / singleInstance 决定:
- 新建实例
- 复用实例
- 清空上方 Activity
- 切换任务栈
步骤 5:旧页面暂停
- AMS 先暂停当前前台 Activity(onPause);
- 必须等待 onPause 执行完成,才能继续。
步骤 6:新页面生命周期调度
- AMS 下发:onCreate → onStart → onResume;
- 全程串行,不可并发。
步骤 7:窗口创建与显示
- AMS 通知 WMS 创建窗口;
- 执行 measure → layout → draw;
- 上屏显示。
步骤 8:状态更新
- 更新 ActivityRecord 状态为 RESUMED;
- 更新进程优先级为前台;
- 更新任务栈与最近任务。
请解释 AMS 在冷启动和热启动中的不同处理方式,核心区别是什么?
冷启动(Cold Start)
定义:应用进程未启动,需要从 Zygote 孵化。
AMS 处理:
- 启动应用进程(fork);
- 初始化 ActivityThread;
- 创建并初始化 Application,执行 onCreate;
- 创建任务栈;
- 完整执行 Activity 生命周期;
- 分配独立虚拟机、内存空间、Binder 环境。
耗时点:进程创建 + Application 初始化。
热启动(Hot Start)
定义:应用进程已存在,Activity 仅处于后台 Stop 状态。
AMS 处理:
- 无需创建进程;
- 无需初始化 Application;
- 直接将任务栈移至前台;
- 执行:onRestart → onStart → onResume;
- 直接恢复窗口,无需重新创建。
速度极快。
核心区别
| 项目 | 冷启动 | 热启动 |
|---|---|---|
| 进程是否创建 | 是 | 否 |
| Application 是否创建 | 是 | 否 |
| 任务栈是否重建 | 可能 | 否 |
| 生命周期 | 完整流程 | 仅恢复流程 |
| AMS 工作量 | 极大 | 极小 |
| 系统资源消耗 | 高 | 低 |
| 速度 | 慢 | 快 |
一句话总结: 冷启动 = 造进程 + 造页面;热启动 = 唤醒进程 + 恢复页面。
十一、启动过程中的资源、调度、异步、异常处理
AMS 在启动 Activity 时如何考虑系统资源的调度?如何避免资源不足导致的启动失败?
AMS 在 Activity 启动时是系统资源的全局调度器,核心目标是保证前台启动优先。
资源调度策略
- CPU 资源倾斜
- 前台启动进程获得最高优先级;
- 暂停后台进程 CPU 调度,减少竞争。
- 内存资源保障
- 启动前检查剩余内存是否足够;
- 不足则提前回收低优先级后台进程;
- 禁止在启动过程中执行大规模 GC。
- IO 调度优化
- 启动期间应用 IO 优先级提升;
- 后台 IO 暂时限流。
- Binder 线程资源保障
- 为启动流程分配专用 Binder 线程;
- 避免被其他 IPC 阻塞。
避免启动失败机制
- 预检查内存阈值,不足先回收再启动;
- 启动超时保护,防止卡死;
- 权限、组件不存在等问题提前拦截;
- 低内存下优先保证系统应用与前台应用启动。
AMS 在处理 Activity 启动的异步操作时,采用了什么机制?如何确保异步操作不阻塞启动流程?
Activity 启动是跨进程、多阶段、异步混合流程,AMS 用一套稳定机制保证不乱序。
核心异步机制
- Binder 异步调用 + 消息队列串行
- AMS 下发生命周期采用异步 Binder 调用;
- 应用端在主线程 Handler 中串行执行。
- Resume 同步屏障
- 只有前一个生命周期完成,才会进入下一步;
- 尤其是 onPause → onResume 之间强同步。
- 启动事务(Transaction)机制
- AMS 为每次启动分配事务 ID;
- 按事务顺序执行,避免并发冲突。
- 超时监控
- 启动超时(如 10s)则视为 ANR;
- AMS 主动清理并报错。
不阻塞保证
- 异步通知,但状态流转严格串行;
- 耗时操作一律放到后台;
- UI 相关生命周期必须在主线程串行;
- AMS 内部使用消息队列,不阻塞系统主线程。
AMS 如何处理 Activity 启动过程中的错误情况?(如权限不足、Activity 不存在、资源不足等)
AMS 在启动每一步都会做异常捕获,并给出明确反馈。
1. 权限不足
- AMS 直接抛出
SecurityException; - 启动中断,应用崩溃或返回错误。
2. Activity 不存在
- 抛出
ActivityNotFoundException; - 无默认处理器则崩溃。
3. 应用被强制停止
- AMS 直接拒绝启动;
- 无任何回调。
4. 进程启动失败
- Zygote fork 失败;
- AMS 重试一次,仍失败则放弃并记录日志。
5. 资源不足(低内存)
- AMS 先回收后台进程;
- 仍不足则拒绝启动,或弹出系统提示。
6. 生命周期超时(ANR)
- onPause / onResume 超时;
- AMS 弹出 ANR 对话框;
- 记录 traces 日志。
7. 崩溃异常
- 应用进程启动后崩溃;
- AMS 清理 ProcessRecord、ActivityRecord;
- 可配置自动重启。
说说 AMS 在启动 Activity 时对系统资源的预分配操作,涉及哪些资源?如何预估和分配?
AMS 在启动前会预估资源需求并预分配,保证启动流畅。
预分配资源类型
- 内存资源
- 预估应用最小可用内存;
- 预留堆内存,避免启动过程 OOM。
- Binder 线程池资源
- 预分配 Binder 线程用于 IPC;
- 防止通信阻塞。
- 文件描述符与 IO 资源
- 提升进程 IO 优先级;
- 预打开关键资源通道。
- CPU 时间片
- 提升进程调度优先级;
- 固定时间片倾斜保证启动速度。
- WMS 窗口资源
- 提前申请窗口、Surface 资源;
- 避免窗口创建失败。
预估与分配逻辑
- 基于进程历史内存占用做估算;
- 系统定义最低保障阈值;
- 前台启动 > 后台启动;
- 资源不足时先杀旧后台,再分配给新启动。
在启动一个具有依赖关系的 Activity 时,AMS 如何协调?(如依赖其他 Activity、服务、资源等)
Activity 可能依赖:其他 Activity、Service、ContentProvider、进程、资源等。
AMS 协调策略
- 依赖 Service
- AMS 先启动并绑定 Service;
- 服务就绪后再启动 Activity。
- 依赖 ContentProvider
- Provider 在 Application 创建前自动初始化;
- 保证 Activity 启动时可直接访问。
- 依赖其他 Activity(跳转链)
- 按启动顺序串行调度;
- 前一个 resume 后再启动下一个。
- 跨进程依赖
- AMS 负责唤醒依赖进程;
- 建立 Binder 连接后再继续。
- 资源依赖(主题、布局等)
- AMS 通知应用进程加载资源;
- 加载失败则启动异常。
核心原则:依赖未就绪 → 启动等待或阻塞;依赖就绪 → 继续执行。
如何通过 AMS 管理 Activity 的启动延时?有哪些优化方式?
AMS 控制启动延时的手段
- 启动优先级调度
- 前台应用延时最低;
- 后台启动被延时、合并、限流。
- 系统繁忙时延时启动
- 高负载下延迟后台 Activity 启动。
- ANR 超时机制
- 严格限制生命周期最大耗时。
- 任务栈调度延时
- 频繁切换时做防抖合并。
优化启动延时的方式
- 减少前台阻塞
- onPause / onResume 不做耗时操作。
- 懒加载初始化
- 非必要逻辑延后到界面显示后。
- 预加载 & 预热
- AMS 对常用应用做进程缓存。
- 配置 android:exported、intent-filter 精简
- 减少 PMS 匹配耗时。
- 热启动优先
- 保持空进程缓存,避免冷启动。
- 启动黑白屏优化
- 设置 windowBackground 减少视觉延时。
十二、权限、安全、系统 / 第三方 Activity 区别
AMS 如何实现跨进程的 Activity 启动?具体流程和安全检查有哪些?
跨进程启动原理
跨进程启动 Activity 的本质是:发起方进程 → Binder → AMS(system_server)→ Binder → 目标进程,AMS 作为唯一中转与管控中心,不允许两个应用进程直接通信启动。
完整流程
- 应用进程调用
startActivity(),通过IActivityManager接口 Binder 调用到 AMS; - AMS 接收请求,解析 Intent、查找目标 Activity 所在进程;
- AMS 检查目标进程是否存在,不存在则请求 Zygote 孵化;
- AMS 进行权限、合法性、启动模式、任务栈等一系列校验;
- AMS 通过
ApplicationThread这个 Binder 接口,跨进程通知目标进程的ActivityThread; - 目标进程主线程实例化 Activity,执行
onCreate → onStart → onResume; - AMS 同步更新任务栈、进程优先级、Activity 状态。
核心安全检查
- Uid/Pid 身份校验 AMS 会获取调用方的 PID、UID,确认进程身份合法。
- Activity 导出状态检查 非系统应用启动外部 Activity 必须满足
android:exported="true",否则直接抛出 SecurityException。 - Permission 权限检查 检查是否拥有
android.permission.START_*等启动权限,检查自定义权限。 - Intent 隐式匹配安全 防止恶意隐式匹配劫持,系统 Activity 会做严格匹配限制。
- 应用状态检查 检查目标应用是否被强制停止、禁用、双开受限。
- 后台启动 Activity 限制(Android 10+) 后台应用不允许随意启动 Activity,必须符合豁免条件。
- 任务栈与 Flag 安全 拦截恶意 Flag,防止越权修改系统任务栈。
AMS 在启动第三方应用的 Activity 时,有哪些特殊操作和安全检查?
第三方应用指非系统、非签名一致的普通第三方 APK,AMS 会执行更严格的沙箱隔离策略。
特殊安全检查
- 严格 exported 检查 第三方 Activity 必须显式设置
exported,否则无法被外部启动。 - 自定义权限校验 若 Activity 设置了
android:permission,调用方必须声明并获取该权限。 - 禁止绕过任务栈管理 不允许第三方应用随意使用系统级 Flag 抢占前台。
- 后台启动限制(Android 10+) 第三方应用在后台时,启动 Activity 会被 AMS 拦截,除非:
- 应用在白名单
- 有通知 pending intent
- 接收系统特殊广播
- UID 隔离与沙箱检查 不同 UID 之间无法直接访问数据,AMS 确保跨进程启动不破坏隔离。
- 防止恶意拉起与链式启动 高版本 Android 中 AMS 会对频繁后台拉起做限流与惩罚。
特殊操作
- 独立任务栈管理,不与系统界面混用关键栈;
- 启动时不赋予系统级窗口优先级;
- 出现 ANR、崩溃时,AMS 只清理目标进程,不影响系统服务;
- 低内存下优先回收第三方后台 Activity;
- 不允许第三方 Activity 覆盖系统关键界面(如输入法、状态栏)。
在启动一个系统级别的 Activity 时,AMS 有哪些额外的处理步骤?
系统 Activity 如:设置、拨号、联系人、关机界面、权限请求页等,AMS 会给予更高优先级与特权处理。
额外处理步骤
- 启动优先级置顶 系统 Activity 可强制抢占前台,不受普通后台启动限制。
- 跳过部分 exported 检查 系统进程间可直接启动非导出 Activity。
- 权限豁免 系统 UID(1000 等)可绕过普通应用权限检查。
- 独立任务栈与窗口层级保障 系统关键页面(如关机、权限弹窗)使用独立栈,不被清理。
- CPU/内存资源优先分配 启动系统界面时,AMS 会临时暂停后台进程调度。
- 禁止被覆盖/被拦截 系统安全界面(锁屏、权限申请)不允许第三方应用遮挡。
- 特殊 Flag 支持 如
FLAG_SHOW_WHEN_LOCKED、FLAG_TURN_SCREEN_ON等高阶 Flag 只对系统开放。 - 崩溃保护机制 核心系统 Activity 崩溃时,AMS 会尝试重启而非直接异常。
- 按键与焦点优先处理 系统界面优先响应 Home、返回、电源键。
AMS 如何确保启动的 Activity 满足系统和用户的权限要求?具体权限检查流程是什么?
AMS 是 Android 权限检查的核心入口,所有跨进程启动必须经过 AMS 权限验证。
完整权限检查流程
- 获取调用者身份 AMS 通过 Binder 调用获取调用方的 PID、UID、包名。
- 获取目标 Activity 所需权限 从 PMS 中读取
AndroidManifest.xml中配置的android:permission。 - 检查是否为系统签名/系统UID 系统应用直接豁免部分权限。
- 检查动态权限(危险权限) 如启动需要相机、位置的 Activity,AMS 检查是否已授权。
- 检查自定义权限 若 Activity 配置自定义权限,校验调用方是否声明。
- 检查 Signature 权限 签名级权限仅相同签名应用可通过。
- 检查特殊权限 如
SYSTEM_ALERT_WINDOW、后台弹出界面权限。 - 检查结果处理
- 校验通过:继续启动流程
- 校验不通过:抛出 SecurityException,终止启动
AMS 核心保障机制
- 权限检查在system_server中执行,应用无法篡改;
- 权限状态实时同步,应用无法本地绕过;
- Android 12+ 对敏感权限启动做额外审计与日志记录。
十三、设备状态、屏幕适配、动画、按键处理
AMS 如何根据设备状态(如电量、网络、过热等)调整 Activity 的启动流程?
AMS 会结合 PowerManagerService、ThermalManagerService 等服务获取设备状态,动态调整启动策略。
不同状态下的调整策略
- 低电量模式
- 降低后台 Activity 启动优先级;
- 延迟非核心页面启动;
- 禁止启动时执行高耗任务。
- 设备过热(Thermal)
- 限制启动过程中的并发操作;
- 延长生命周期执行间隔,降低 CPU 占用;
- 禁止后台应用启动 Activity。
- 网络状态差
- 不影响启动本身,但 AMS 通知应用延迟网络请求;
- 不阻塞 UI 显示。
- 省电模式 / 超级省电
- 只允许前台和白名单应用启动;
- 冻结第三方后台启动;
- 减少动画、过渡效果,降低渲染开销。
- 屏幕关闭状态
- 除系统闹钟、来电外,拦截第三方 Activity 启动;
- 不允许应用无故亮屏启动。
AMS 在启动 Activity 时,如何处理不同的屏幕分辨率和密度?如何确保布局适配?
AMS 不负责具体布局绘制,但负责配置分发与生命周期调度,真正渲染由 WMS 和应用自身完成。
AMS 核心处理
- 读取设备显示配置 从 WMS 或
DisplayManager获取密度、分辨率、方向、屏幕尺寸。 - 将 Configuration 分发给应用进程 ActivityThread 收到配置后,应用根据
res/下对应资源目录加载布局、图片。 - 处理配置变化 分辨率、密度、折叠屏变化时,AMS 触发:
- 标准模式:销毁重建 Activity
android:configChanges模式:回调onConfigurationChanged()
- 协调窗口大小 AMS 通知 WMS 分配窗口大小,确保 Activity 窗口匹配屏幕区域。
- 折叠屏/分屏模式适配 AMS 调整任务栈大小,通知应用进入多窗口模式。
布局适配保障
- AMS 保证应用获取正确的 Configuration;
- 系统根据 density 自动选择
drawable-xxxhdpi、layout-land等资源; - 应用不处理配置变化时,AMS 保证重建后恢复状态。
请解释 AMS 在启动 Activity 时对动画的初始化操作,如何与 WindowManagerService 协同实现动画播放?
Activity 切换动画由 AMS 调度 + WMS 执行 共同完成。
AMS 初始化操作
- 确定切换场景: 新启动、返回、任务切换、分屏调整;
- 根据启动 Flag、Activity 主题、系统设置选择动画类型;
- 在
ActivityStack中记录动画开始时机,确保生命周期与动画同步; - 等待新 Activity
onResume完成后,通知 WMS 开始动画。
AMS 与 WMS 协同流程
- AMS 完成栈管理、生命周期调度;
- AMS 调用 WMS 接口,为新旧窗口设置动画;
- WMS 负责窗口的尺寸、位置、透明度、过渡动画计算;
- WMS 把渲染指令交给 SurfaceFlinger 执行;
- 动画结束后,WMS 通知 AMS 更新栈状态;
- AMS 执行旧页面
onStop等后续生命周期。
关键协同点
- AMS 控制何时开始动画;
- WMS 控制动画怎么执行;
- 动画期间不阻塞生命周期,但会同步时序。
AMS 如何管理 Home 键和返回键的行为?具体处理流程是什么?
Home、返回键均由 AMS 统一接管逻辑,应用只能监听不能篡改系统行为。
返回键(Back)处理流程
- 用户点击返回键,事件由 ViewRootImpl → WMS → AMS;
- AMS 查询当前前台任务栈与栈顶 Activity;
- 栈内 Activity 数量 > 1:
- AMS 调度当前 Activity 执行
onPause → onStop → onDestroy; - 上一个 Activity 恢复
onRestart → onStart → onResume;
- AMS 调度当前 Activity 执行
- 栈内只剩根 Activity:
- AMS 将任务栈移至后台;
- 应用进入后台,返回桌面;
- 支持
onBackPressed()拦截,但最终出栈逻辑仍由 AMS 控制。
Home 键处理流程
- Home 键事件直接由系统服务处理,应用无法拦截;
- AMS 将当前任务栈移至后台;
- 当前 Activity 执行
onPause → onStop; - 进程优先级从前台降为后台;
- AMS 切换到 Launcher 所在任务栈,显示桌面;
- 不销毁 Activity,保留状态以便快速恢复。
十四、Service 启动与多任务稳定性
AMS 如何启动服务?它与启动 Activity 有什么核心区别?
AMS 启动 Service 流程
- 应用调用
startService/bindService,通过 Binder 进入 AMS; - AMS 检查权限、进程状态、Service 配置;
- 目标进程不存在则创建进程;
- AMS 通知应用进程创建 Service 实例;
- 执行
onCreate → onStartCommand或onBind; - AMS 维护
ServiceRecord,管理服务生命周期。
与启动 Activity 的核心区别
- 有无界面与任务栈
- Activity 有界面、有窗口、归属任务栈;
- Service 无 UI,不进入任务栈。
- 生命周期回调不同
- Activity:onCreate → onStart → onResume → onPause → onStop → onDestroy
- Service:onCreate → onStartCommand / onBind → onDestroy
- 用户可见性不同
- Activity 直接可见可交互;
- Service 后台不可见。
- 调度优先级不同
- 前台 Activity 优先级 > 前台 Service > 后台 Service;
- 后台限制不同
- Android 8.0+ 严格限制后台 Service,而 Activity 不受同等限制;
- 回收策略不同
- Activity 在 Stop 后可被系统销毁;
- Service 被系统回收后可通过
START_STICKY重启。
- 启动目的不同
- Activity 负责交互;
- Service 负责后台长期任务。
AMS 如何保证多任务处理时的稳定性和流畅性?有哪些核心优化手段?
多任务指:最近任务切换、多应用后台运行、分屏、小窗等场景。AMS 通过全局调度保证系统不卡顿、不崩溃。
核心优化手段
- 进程优先级动态调整 前台任务最高,后台任务降级,避免抢占资源。
- 严格生命周期串行调度 同一时刻只执行一个页面的切换,避免并发导致卡顿。
- 低内存下分级回收 空进程 → 后台进程 → 服务进程,不影响前台可见任务。
- 后台进程冻结机制 闲置后台进程被冻结,不消耗 CPU,降低功耗与卡顿。
- 任务栈隔离管理 不同任务栈互不干扰,一个应用崩溃不影响全局。
- 启动与切换资源倾斜 切换时优先分配 CPU、内存、IO 给前台任务。
- ANR 监控与超时保护 生命周期超时自动触发 ANR 清理,避免系统卡死。
- 窗口切换与动画优化 与 WMS 协同,减少过渡卡顿,降低渲染压力。
- 限制后台进程数量 防止过多进程占用内存导致 OOM。
- 崩溃隔离机制 应用进程崩溃只清理自身记录,不导致 system_server 崩溃。
- 分屏/多窗口资源公平调度 多个前台任务分时复用 CPU,保证同时流畅。
稳定性最终目标
- 前台应用不卡顿
- 系统不死机、不重启
- 多应用切换无黑屏、无白屏、无 ANR
- 内存稳定不暴涨