727 lines
22 KiB
Plaintext
727 lines
22 KiB
Plaintext
|
|
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>标签,创建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. 关键接口
|
|||
|
|
- 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与其他系统服务的协作
|
|||
|
|
- 了解进程管理和内存回收机制
|
|||
|
|
- 能够分析性能问题和优化方案
|