From 2351d55a8a092a4ef26cae8d33919b7857e52d51 Mon Sep 17 00:00:00 2001 From: renjianbo <18691577328@163.com> Date: Fri, 16 Jan 2026 16:20:41 +0800 Subject: [PATCH] =?UTF-8?q?=E9=8F=87=E5=AD=98=E6=9F=8A=E9=8F=82=E5=9B=A8?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .obsidian/workspace.json | 8 +- ams常见面试题.txt | 726 +++++++++++++++++++++++++++ docs/android面试/系统原理/AMS面试.md | 726 +++++++++++++++++++++++++++ mkdocs.yml | 1 + 4 files changed, 1457 insertions(+), 4 deletions(-) create mode 100644 ams常见面试题.txt create mode 100644 docs/android面试/系统原理/AMS面试.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index faf42f7..4bda4c1 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -198,8 +198,10 @@ "command-palette:打开命令面板": false } }, - "active": "5b497a77c6d68c73", + "active": "25c9f7051aac05b3", "lastOpenFiles": [ + "docs/android面试/系统原理/AMS面试.md", + "ams常见面试题.txt", "docs/android面试/系统原理/WMS面试.md", "docs/Obsidian笔记体系/Projects/saars开发/aiapply/未命名 1.md", "docs/Obsidian笔记体系/Projects/saars开发/aiapply/未命名.md", @@ -226,7 +228,6 @@ "docs/Google开发文档体系/核心主题/Jetpack组件.md", "docs/Google开发文档体系/示例代码/架构示例.md", "docs/Google开发文档体系/示例代码/官方示例项目.md", - "docs/Google开发文档体系/示例代码/代码片段.md", "docs/Google开发文档体系/视频和教程", "docs/Google开发文档体系/核心主题", "docs/Google开发文档体系/示例代码", @@ -234,7 +235,6 @@ "docs/Google开发文档体系/工具和资源", "docs/Google开发文档体系/入门指南", "docs/Google开发文档体系/API参考", - "docs/Google开发文档体系", - "docs/android面试/技术面试问题回答.txt" + "docs/Google开发文档体系" ] } \ No newline at end of file diff --git a/ams常见面试题.txt b/ams常见面试题.txt new file mode 100644 index 0000000..e7935c4 --- /dev/null +++ b/ams常见面试题.txt @@ -0,0 +1,726 @@ +AMS常见面试题 + +================================================================================ +一、AMS基础概念 +================================================================================ + +Q1: 什么是AMS?它的作用是什么? + +A: AMS(ActivityManagerService)是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进程:启动各类系统服务 + - 启动AMS(ActivityManagerService) + - 启动WMS(WindowManagerService) + - 启动PMS(PackageManagerService) + - 启动其他系统服务 +6. AMS启动Launcher:系统服务就绪后,AMS启动Launcher应用 + +Q3: AMS与其他系统服务的关系? + +A: AMS与其他系统服务的关系: +1. AMS与WMS:AMS负责Activity的生命周期,WMS负责窗口的显示和布局 +2. AMS与PMS:AMS需要PMS提供包信息来启动Activity +3. AMS与Zygote:AMS通过Zygote创建新进程 +4. AMS与Binder:AMS通过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通知AMS:Activity启动完成 + +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通知AMS:Service创建完成 + +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信息 +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()) +- 效率较低 + +优先级设置: +- 静态注册:在中设置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. 关键接口 + - IActivityManager:AMS的Binder接口 + - IApplicationThread:ApplicationThread的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与其他系统服务的协作 +- 了解进程管理和内存回收机制 +- 能够分析性能问题和优化方案 diff --git a/docs/android面试/系统原理/AMS面试.md b/docs/android面试/系统原理/AMS面试.md new file mode 100644 index 0000000..e7935c4 --- /dev/null +++ b/docs/android面试/系统原理/AMS面试.md @@ -0,0 +1,726 @@ +AMS常见面试题 + +================================================================================ +一、AMS基础概念 +================================================================================ + +Q1: 什么是AMS?它的作用是什么? + +A: AMS(ActivityManagerService)是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进程:启动各类系统服务 + - 启动AMS(ActivityManagerService) + - 启动WMS(WindowManagerService) + - 启动PMS(PackageManagerService) + - 启动其他系统服务 +6. AMS启动Launcher:系统服务就绪后,AMS启动Launcher应用 + +Q3: AMS与其他系统服务的关系? + +A: AMS与其他系统服务的关系: +1. AMS与WMS:AMS负责Activity的生命周期,WMS负责窗口的显示和布局 +2. AMS与PMS:AMS需要PMS提供包信息来启动Activity +3. AMS与Zygote:AMS通过Zygote创建新进程 +4. AMS与Binder:AMS通过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通知AMS:Activity启动完成 + +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通知AMS:Service创建完成 + +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信息 +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()) +- 效率较低 + +优先级设置: +- 静态注册:在中设置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. 关键接口 + - IActivityManager:AMS的Binder接口 + - IApplicationThread:ApplicationThread的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与其他系统服务的协作 +- 了解进程管理和内存回收机制 +- 能够分析性能问题和优化方案 diff --git a/mkdocs.yml b/mkdocs.yml index 97efe30..319d57f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -289,6 +289,7 @@ nav: - android面试/项目经验/技术选型.md - android面试/项目经验/问题排查经验.md - android面试/项目经验/项目架构设计.md + - android面试/系统原理/AMS面试.md - Google开发文档体系: - Google开发文档体系/API参考/Android_API概览.md - Google开发文档体系/API参考/Jetpack_API.md