Files
mkdocs/ams常见面试题.txt
2026-01-16 16:20:41 +08:00

727 lines
22 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
AMS常见面试题
================================================================================
一、AMS基础概念
================================================================================
Q1: 什么是AMS它的作用是什么
A: AMSActivityManagerService是Android系统的核心服务之一运行在system_server进程中。
主要作用:
1. Activity生命周期管理管理Activity的创建、启动、暂停、停止、销毁等生命周期
2. Service生命周期管理管理Service的启动、绑定、停止等
3. BroadcastReceiver管理管理广播的注册、发送、接收
4. 进程管理:管理应用进程的创建、销毁、优先级调整
5. 任务栈管理管理Activity任务栈Task Stack处理启动模式、Intent Flag等
6. 内存管理:监控应用内存使用,进行进程回收和内存优化
Q2: AMS在系统启动流程中的位置
A: AMS在系统启动流程中的位置
1. Bootloader阶段加载Linux内核
2. Kernel启动初始化硬件启动init进程
3. Init进程解析init.rc启动Zygote和ServiceManager
4. Zygote进程预加载类和资源fork出SystemServer进程
5. SystemServer进程启动各类系统服务
- 启动AMSActivityManagerService
- 启动WMSWindowManagerService
- 启动PMSPackageManagerService
- 启动其他系统服务
6. AMS启动Launcher系统服务就绪后AMS启动Launcher应用
Q3: AMS与其他系统服务的关系
A: AMS与其他系统服务的关系
1. AMS与WMSAMS负责Activity的生命周期WMS负责窗口的显示和布局
2. AMS与PMSAMS需要PMS提供包信息来启动Activity
3. AMS与ZygoteAMS通过Zygote创建新进程
4. AMS与BinderAMS通过Binder机制与应用进程通信
================================================================================
二、Activity启动流程
================================================================================
Q4: 请详细描述Activity的启动流程
A: Activity启动流程以跨进程启动为例
客户端进程应用A
1. Activity.startActivity(Intent intent)
2. Instrumentation.execStartActivity()
3. ActivityManager.getService().startActivity()
- 通过Binder调用AMS的startActivity方法
服务端进程system_server
4. ActivityManagerService.startActivity()
5. ActivityManagerService.startActivityAsUser()
6. ActivityStarter.startActivity()
- 检查权限和Intent
- 解析目标Activity信息
7. ActivityStarter.startActivityUnchecked()
- 处理启动模式standard、singleTop、singleTask、singleInstance
- 处理Intent Flag
8. ActivityStackSupervisor.startActivityLocked()
- 创建或查找ActivityRecord
- 查找或创建任务栈Task
9. ActivityStack.startActivityLocked()
- 将ActivityRecord添加到任务栈
10. ActivityStack.resumeTopActivityLocked()
- 暂停当前Activity
- 准备启动目标Activity
11. ActivityStackSupervisor.realStartActivityLocked()
- 检查目标进程是否存在
- 如果不存在通过Zygote创建新进程
- 通过ApplicationThread发送启动消息
目标进程应用B
12. ApplicationThread.scheduleLaunchActivity()
- 接收AMS的启动消息
13. ActivityThread.handleLaunchActivity()
- 创建Activity实例
- 调用Activity.attach()
- 调用Activity.onCreate()
14. ActivityThread.performResumeActivity()
- 调用Activity.onStart()
- 调用Activity.onResume()
15. 通过Binder通知AMSActivity启动完成
Q5: Activity启动过程中AMS如何检查权限
A: AMS在启动Activity时会进行以下权限检查
1. 目标Activity的exported属性检查
- 如果exported=false只有同应用可以启动
- 如果exported=true其他应用可以启动
2. 权限检查
- 检查调用方是否有启动目标Activity的权限
- 检查目标Activity声明的权限要求
3. Intent Filter匹配
- 如果是隐式Intent检查Intent Filter是否匹配
4. 签名权限检查
- 如果目标Activity声明了签名权限检查调用方签名
关键代码位置:
- ActivityStarter.checkStartActivityPermission()
- ActivityStarter.resolveActivity()
Q6: Activity的启动模式是如何在AMS中实现的
A: AMS通过ActivityStack和ActivityRecord管理启动模式
1. standard模式标准模式
- 每次启动都创建新的ActivityRecord
- 添加到当前任务栈顶部
2. singleTop模式栈顶复用
- 检查栈顶Activity是否为目标Activity
- 如果是复用并调用onNewIntent()
- 如果不是,创建新实例
3. singleTask模式栈内复用
- 检查任务栈中是否存在目标Activity
- 如果存在复用并清理其上方的Activity
- 如果不存在,创建新实例
4. singleInstance模式单实例
- 创建独立的任务栈
- 该栈中只有这一个Activity
关键代码位置:
- ActivityStarter.startActivityUnchecked()
- ActivityStack.findActivityLocked()
- ActivityStack.startActivityLocked()
Q7: Intent Flag是如何影响Activity启动的
A: 常见的Intent Flag及其在AMS中的处理
1. FLAG_ACTIVITY_NEW_TASK
- 创建新的任务栈
- 如果任务栈已存在,则复用
2. FLAG_ACTIVITY_CLEAR_TOP
- 如果目标Activity在栈中清理其上方的Activity
- 复用目标Activity并调用onNewIntent()
3. FLAG_ACTIVITY_SINGLE_TOP
- 效果类似singleTop启动模式
- 如果栈顶是目标Activity复用
4. FLAG_ACTIVITY_CLEAR_TASK
- 清除任务栈中所有Activity
- 然后启动目标Activity
5. FLAG_ACTIVITY_REORDER_TO_FRONT
- 如果目标Activity在栈中将其移到栈顶
- 不创建新实例
关键代码位置:
- ActivityStarter.computeLaunchingTaskFlags()
- ActivityStack.startActivityLocked()
================================================================================
三、Service启动流程
================================================================================
Q8: Service的启动流程是怎样的
A: Service启动流程
客户端进程:
1. Context.startService(Intent intent)
2. ContextImpl.startService()
3. ActivityManager.getService().startService()
- 通过Binder调用AMS
服务端进程system_server
4. ActivityManagerService.startService()
5. ActiveServices.startServiceLocked()
- 检查Service是否已启动
- 创建ServiceRecord
6. ActiveServices.bringUpServiceLocked()
- 检查目标进程是否存在
- 如果不存在通过Zygote创建进程
7. ActiveServices.realStartServiceLocked()
- 通过ApplicationThread发送创建消息
目标进程:
8. ApplicationThread.scheduleCreateService()
9. ActivityThread.handleCreateService()
- 创建Service实例
- 调用Service.onCreate()
10. 通过Binder通知AMSService创建完成
Q9: Service的绑定流程是怎样的
A: Service绑定流程
客户端进程:
1. Context.bindService(Intent intent, ServiceConnection conn, int flags)
2. ContextImpl.bindService()
3. ActivityManager.getService().bindService()
- 通过Binder调用AMS
服务端进程:
4. ActivityManagerService.bindService()
5. ActiveServices.bindServiceLocked()
- 检查Service是否已启动
- 如果未启动先启动Service
6. ActiveServices.requestServiceBindingLocked()
- 创建ConnectionRecord
- 通过ApplicationThread发送绑定消息
目标进程:
7. ApplicationThread.scheduleBindService()
8. ActivityThread.handleBindService()
- 调用Service.onBind()
- 返回IBinder对象
9. 通过Binder将IBinder传递给客户端
10. 客户端ServiceConnection.onServiceConnected()被调用
Q10: Service的启动和绑定有什么区别
A: 启动和绑定的区别:
启动startService
- 生命周期onCreate() -> onStartCommand() -> onDestroy()
- 独立运行Service独立于启动它的组件运行
- 停止方式调用stopService()或Service.stopSelf()
- 适用场景:后台任务、音乐播放等
绑定bindService
- 生命周期onCreate() -> onBind() -> onUnbind() -> onDestroy()
- 依赖关系Service与绑定它的组件生命周期关联
- 停止方式:所有组件解绑后自动停止
- 适用场景需要与Activity交互、提供接口给其他组件
混合模式:
- 可以同时启动和绑定
- 需要同时调用stopService()和解绑才会销毁
================================================================================
四、BroadcastReceiver流程
================================================================================
Q11: BroadcastReceiver的注册流程是怎样的
A: BroadcastReceiver注册流程
静态注册AndroidManifest.xml
1. 系统启动时PMS解析AndroidManifest.xml
2. 发现<receiver>标签创建Receiver信息
3. 注册到AMS的ReceiverList中
动态注册(代码中):
1. Context.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
2. ContextImpl.registerReceiver()
3. ActivityManager.getService().registerReceiver()
- 通过Binder调用AMS
4. ActivityManagerService.registerReceiver()
- 创建ReceiverList
- 保存到AMS的mRegisteredReceivers中
Q12: 广播的发送和接收流程是怎样的?
A: 广播发送和接收流程:
发送广播:
1. Context.sendBroadcast(Intent intent)
2. ContextImpl.sendBroadcast()
3. ActivityManager.getService().broadcastIntent()
- 通过Binder调用AMS
AMS处理
4. ActivityManagerService.broadcastIntent()
5. BroadcastQueue.enqueueBroadcast()
- 将广播加入队列
6. BroadcastQueue.scheduleBroadcastsLocked()
- 调度广播分发
接收广播:
7. BroadcastQueue.processNextBroadcast()
- 查找匹配的Receiver
- 按优先级排序
8. 对于动态注册的Receiver
- 通过ApplicationThread.scheduleReceiver()
- 发送到目标进程
9. 对于静态注册的Receiver
- 如果进程不存在,先启动进程
- 然后发送广播
10. ActivityThread.handleReceiver()
- 创建Receiver实例
- 调用Receiver.onReceive()
11. 如果是有序广播等待当前Receiver处理完成后再发送下一个
Q13: 有序广播和普通广播的区别?
A: 有序广播Ordered Broadcast和普通广播的区别
普通广播sendBroadcast
- 所有Receiver同时接收
- 无法中断传播
- 无法传递结果
- 效率较高
有序广播sendOrderedBroadcast
- Receiver按优先级顺序接收
- 可以中断传播abortBroadcast()
- 可以传递结果setResult()
- 效率较低
优先级设置:
- 静态注册:在<intent-filter>中设置android:priority
- 动态注册在IntentFilter中设置setPriority()
================================================================================
五、进程管理
================================================================================
Q14: AMS如何管理应用进程
A: AMS的进程管理机制
1. 进程创建
- 当需要启动Activity/Service时检查目标进程是否存在
- 如果不存在通过Zygote创建新进程
- 创建ProcessRecord记录进程信息
2. 进程优先级
- FOREGROUND_APP前台应用优先级最高
- VISIBLE_APP可见应用
- SERVICE后台服务
- BACKGROUND_APP后台应用
- EMPTY_APP空进程优先级最低
3. 进程回收Low Memory Killer
- 当系统内存不足时,按优先级回收进程
- 优先回收EMPTY_APP、BACKGROUND_APP
- 最后回收FOREGROUND_APP
4. 进程通信
- 通过Binder机制与应用进程通信
- ApplicationThread是应用进程的Binder服务端
Q15: AMS如何判断进程是否需要回收
A: AMS判断进程是否需要回收的因素
1. 进程优先级
- 优先级越低,越容易被回收
2. 内存使用情况
- 进程占用的内存越大,越容易被回收
3. 进程状态
- 空进程没有Activity、Service、Receiver优先回收
- 后台进程次之
- 前台进程最后回收
4. 用户交互
- 最近使用的进程不容易被回收
- 长时间未使用的进程容易被回收
5. 进程重要性
- 系统进程不会被回收
- 关键服务进程不容易被回收
关键代码位置:
- ActivityManagerService.updateOomAdjLocked()
- ProcessList.computeOomAdjLocked()
================================================================================
六、任务栈管理
================================================================================
Q16: 什么是任务栈Task Stack
A: 任务栈Task Stack是AMS用来管理Activity的栈结构
1. 任务Task定义
- 用户为了完成某项工作而交互的Activity集合
- 一个任务栈包含多个ActivityRecord
2. 任务栈特点
- 后进先出LIFO最后启动的Activity在栈顶
- 返回键导航按返回键会依次关闭栈顶Activity
- 独立管理不同应用的Activity可以在不同任务栈中
3. 任务栈标识
- taskId任务栈的唯一标识
- taskAffinity任务栈的亲和性相同affinity的Activity在同一栈
4. 任务栈管理
- ActivityStack管理单个任务栈
- ActivityStackSupervisor管理所有任务栈
Q17: Activity的启动模式如何影响任务栈
A: 启动模式对任务栈的影响:
1. standard模式
- 每次启动创建新ActivityRecord
- 添加到调用方所在的任务栈
2. singleTop模式
- 如果栈顶是目标Activity复用
- 否则创建新实例,添加到当前栈
3. singleTask模式
- 查找或创建具有相同taskAffinity的任务栈
- 如果栈中存在目标Activity复用并清理上方Activity
- 如果不存在,创建新实例
4. singleInstance模式
- 创建独立的任务栈
- 该栈中只有这一个Activity
- 其他Activity不能进入该栈
关键代码位置:
- ActivityStarter.computeLaunchingTaskFlags()
- ActivityStack.findActivityLocked()
================================================================================
七、AMS源码分析
================================================================================
Q18: AMS的关键类有哪些
A: AMS的关键类
1. ActivityManagerService
- AMS的主类系统服务的实现
- 管理所有Activity、Service、Receiver
2. ActivityStack
- 管理单个任务栈
- 处理Activity的入栈、出栈、生命周期
3. ActivityStackSupervisor
- 管理所有任务栈
- 协调多个ActivityStack
4. ActivityStarter
- 处理Activity启动逻辑
- 检查权限、处理启动模式、Intent Flag
5. ActivityRecord
- 表示一个Activity实例
- 存储Activity的状态、配置等信息
6. ProcessRecord
- 表示一个应用进程
- 存储进程信息、进程中的Activity/Service
7. ServiceRecord
- 表示一个Service实例
- 存储Service的状态、绑定信息
8. ReceiverList
- 表示BroadcastReceiver列表
- 管理动态注册的Receiver
Q19: AMS的关键方法有哪些
A: AMS的关键方法
Activity相关
- startActivity()启动Activity
- startActivityAsUser()以指定用户身份启动Activity
- finishActivity()结束Activity
- resumeTopActivityLocked()恢复栈顶Activity
Service相关
- startService()启动Service
- bindService()绑定Service
- stopService()停止Service
- unbindService()解绑Service
Broadcast相关
- registerReceiver()注册Receiver
- unregisterReceiver()注销Receiver
- broadcastIntent():发送广播
进程管理:
- startProcessLocked():启动进程
- killProcessLocked():杀死进程
- updateOomAdjLocked():更新进程优先级
Q20: AMS如何与应用进程通信
A: AMS与应用进程的通信机制
1. Binder机制
- AMS作为Binder服务端运行在system_server进程
- 应用进程通过ActivityManager.getService()获取AMS代理
- 通过Binder调用AMS的方法
2. ApplicationThread
- ApplicationThread是应用进程的Binder服务端
- AMS通过ApplicationThread向应用进程发送消息
- 应用进程通过ApplicationThread接收AMS的指令
3. 通信流程
应用进程 -> Binder -> AMS启动Activity
AMS -> ApplicationThread -> 应用进程创建Activity
4. 关键接口
- IActivityManagerAMS的Binder接口
- IApplicationThreadApplicationThread的Binder接口
================================================================================
八、性能优化与问题排查
================================================================================
Q21: 如何优化Activity启动速度
A: Activity启动速度优化
1. Application优化
- 减少Application.onCreate()中的初始化
- 延迟初始化非关键组件
- 使用App Startup统一管理初始化
2. Activity优化
- 减少onCreate()中的耗时操作
- 使用异步加载数据
- 优化布局层级
3. 进程优化
- 避免不必要的进程创建
- 使用进程保活策略(谨慎使用)
4. 系统优化
- 减少AMS处理时间
- 优化Binder通信
- 减少跨进程调用
Q22: 如何排查AMS相关的问题
A: AMS问题排查方法
1. 日志分析
- 查看logcat中的AMS相关日志
- 关注ActivityManager、ActivityTaskManager标签
- 使用adb logcat | grep -i "activitymanager"
2. 使用工具
- Systrace分析Activity启动时间线
- Perfetto分析系统整体性能
- dumpsys activity查看Activity栈信息
3. 常见问题
- ANR检查AMS响应时间
- 启动慢:分析启动流程各阶段耗时
- 内存泄漏检查ActivityRecord是否正确释放
4. 调试命令
- adb shell dumpsys activity activities查看Activity栈
- adb shell dumpsys activity services查看Service信息
- adb shell dumpsys activity broadcasts查看广播信息
Q23: 如何分析Activity启动性能
A: Activity启动性能分析
1. 使用Systrace
- 抓取启动过程的trace
- 分析各阶段耗时
- 重点关注AMS处理时间
2. 使用Perfetto
- 更详细的性能分析
- 可以查看Binder调用
- 分析进程创建时间
3. 代码埋点
- 在关键位置添加时间戳
- 记录各阶段耗时
- 分析瓶颈
4. 关键指标
- 冷启动时间:从点击到首帧显示
- 热启动时间从点击到Activity可见
- AMS处理时间AMS处理启动请求的时间
================================================================================
九、高级问题
================================================================================
Q24: AMS如何处理多窗口模式
A: AMS在多窗口模式下的处理
1. 多窗口类型
- 分屏模式Split Screen
- 画中画模式Picture-in-Picture
- 自由窗口模式Freeform
2. 任务栈管理
- 每个窗口有独立的任务栈
- 不同窗口的Activity可以同时运行
- 需要协调多个ActivityStack
3. 生命周期管理
- 非焦点窗口的Activity进入onPause()
- 焦点窗口的Activity保持onResume()
- 窗口切换时触发生命周期变化
4. 关键类
- ActivityStack管理单个任务栈
- DisplayContent管理显示内容
- TaskStack任务栈管理
Q25: AMS如何与WMS协作
A: AMS与WMS的协作
1. 职责分工
- AMS管理Activity生命周期、任务栈
- WMS管理窗口显示、布局、输入事件
2. 协作流程
- AMS启动Activity后通知WMS创建窗口
- WMS创建窗口后通知AMS窗口已就绪
- AMS管理Activity生命周期WMS管理窗口显示
3. 关键交互
- Activity创建窗口通过WindowManager.addView()
- 窗口状态同步AMS和WMS同步窗口状态
- 输入事件WMS将输入事件分发给AMS管理的Activity
4. 通信机制
- 通过Binder机制通信
- 通过回调机制同步状态
================================================================================
十、实战问题
================================================================================
Q26: 如何实现Activity的保活
A: Activity保活方法不推荐仅作了解
1. 前台服务
- 启动前台Service
- 显示通知
- 提高进程优先级
2. 1像素Activity
- 在锁屏时启动1像素透明Activity
- 提高进程优先级
- 解锁时关闭
3. 双进程守护
- 两个进程互相守护
- 一个进程被杀,另一个进程重启它
注意:这些方法会影响用户体验和系统性能,不推荐使用。
Q27: 如何实现Activity的预加载
A: Activity预加载方法
1. 提前创建进程
- 在Application中提前启动目标进程
- 预热进程,减少启动时间
2. 预加载数据
- 提前加载Activity需要的数据
- 使用缓存机制
3. 使用启动器
- 使用App Startup管理初始化
- 控制初始化顺序
4. 优化布局
- 减少布局复杂度
- 使用ViewStub延迟加载
Q28: 如何监控AMS的性能
A: AMS性能监控方法
1. 系统指标
- 使用dumpsys activity获取性能数据
- 监控进程创建时间
- 监控Activity启动时间
2. 日志分析
- 分析AMS相关日志
- 统计各操作耗时
- 找出性能瓶颈
3. 工具使用
- Systrace分析启动流程
- Perfetto详细性能分析
- Android Profiler实时监控
4. 自定义监控
- 在关键位置添加埋点
- 统计各阶段耗时
- 上报性能数据
================================================================================
总结
================================================================================
AMS是Android系统的核心服务负责管理Activity、Service、BroadcastReceiver等组件的生命周期。
关键知识点:
1. AMS的职责和架构
2. Activity启动流程跨进程
3. Service启动和绑定流程
4. BroadcastReceiver注册和接收流程
5. 进程管理和任务栈管理
6. AMS源码关键类和方法
7. 性能优化和问题排查
面试重点:
- 深入理解Activity启动流程
- 掌握AMS与其他系统服务的协作
- 了解进程管理和内存回收机制
- 能够分析性能问题和优化方案