引言
在上一篇文章中,我们见证了Zygote如何"孵化"应用进程,但进程诞生后的生命历程由谁来管理?Activity如何启动?进程优先级如何决定?内存不足时哪个进程会被杀掉?
这一切的答案都指向ActivityManagerService(AMS)------Android系统中最核心、最复杂的系统服务之一。
想象这样一个场景:你同时打开了微信、Chrome和抖音,切换应用时系统秒开,内存吃紧时后台应用自动被杀掉却不影响前台体验。这背后的"指挥官"就是AMS。
scss
你点击应用图标
↓
Launcher通知AMS
↓
AMS检查进程是否存在
↓ (不存在)
AMS通知Zygote fork新进程
↓
AMS启动Activity并管理生命周期
↓
AMS持续监控进程状态,调整优先级
↓ (内存不足时)
AMS决定杀掉哪个进程(基于adj值)
📖 系列前置阅读:建议先阅读第13篇(Zygote进程孵化),理解应用进程的创建过程。
AMS是什么?
AMS的"分家"史:从AMS到AMS+ATMS
在Android 10之前,ActivityManagerService是一个"超级服务",负责Activity、Service、Broadcast、ContentProvider、进程管理、内存管理等几乎所有应用生命周期相关的工作。这导致代码臃肿(超过2万行)、职责不清、难以维护。
Android 10重大重构:Google将AMS拆分为两部分:
| 服务 | 职责 | 核心功能 |
|---|---|---|
| AMS | 进程与生命周期管理 | 进程启动/销毁、OOM Adj调整、Service/Broadcast管理 |
| ATMS | Activity任务管理 | Activity启动/生命周期、任务栈管理、窗口状态 |
拆分的好处:
- ✅ 职责清晰: ATMS专注窗口任务,AMS专注进程管理
- ✅ 代码简化: 单个服务代码量减少约40%
- ✅ 性能优化: 减少锁竞争,提升多任务切换性能
- ✅ 可维护性: 模块化设计,更容易添加新特性
AMS的核心职责
1. 进程生命周期管理
- 进程创建请求(通过Zygote)
- 进程优先级调整(OOM Adj机制)
- 进程销毁决策(LMK配合)
2. 四大组件管理
- Service启动/绑定/停止
- Broadcast注册/发送/接收
- ContentProvider发布/查询
- Activity管理(Android 10+由ATMS负责)
3. 系统状态管理
- 应用ANR监控
- 内存状态监控
- 电池优化(Doze/App Standby)
ATMS的核心职责
1. Activity任务管理
- Activity启动流程协调
- 生命周期回调管理
- 配置变更处理
2. 任务栈管理
- Task栈创建/切换
- 启动模式处理(standard/singleTop/singleTask/singleInstance)
- Recent任务管理
3. 窗口状态管理
- 与WindowManagerService协作
- 多窗口/分屏模式
- 画中画(PiP)模式
AMS与ATMS的架构关系
整体架构图
为了帮助理解AMS和ATMS的协作关系,下图展示了完整的架构:

图:AMS与ATMS分工协作,ATMS负责Activity任务管理,AMS负责进程与生命周期管理,两者通过ActivityManagerInternal/ActivityTaskManagerInternal接口通信
这张图涵盖了:
- 应用层: App进程通过Binder调用AMS/ATMS
- ATMS层: Activity启动、栈管理、生命周期
- AMS层: 进程管理、OOM Adj、Service/Broadcast
- 底层协作: Zygote进程创建、WMS窗口管理、LMK内存回收
接下来,我们将逐一深入这些核心机制的源码实现。
Activity启动流程深度解析
启动流程全景
Activity启动涉及多个进程和系统服务的协作,是Android中最复杂的流程之一。
scss
┌─────────────────────────────────────────────────────────────┐
│ 应用进程A (Launcher) │
│ - 调用startActivity() │
│ - 通过Binder调用ATMS │
└────────────┬────────────────────────────────────────────────┘
│ Binder IPC
↓
┌─────────────────────────────────────────────────────────────┐
│ SystemServer进程 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ATMS (ActivityTaskManagerService) │ │
│ │ 1. 权限检查 │ │
│ │ 2. 解析Intent,找到目标Activity │ │
│ │ 3. 检查目标进程是否存在 │ │
│ │ 4. 如果不存在,通知AMS创建进程 │ │
│ │ 5. 如果存在,直接启动Activity │ │
│ └──────────────┬──────────────────────────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────────────────────────┐ │
│ │ AMS (ActivityManagerService) │ │
│ │ - 调用Process.start()通知Zygote │ │
│ │ - 等待新进程启动完成 │ │
│ └─────────────────────────────────────────────────────┘ │
└────────────┬────────────────────────────────────────────────┘
│ Socket: /dev/socket/zygote
↓
┌─────────────────────────────────────────────────────────────┐
│ Zygote进程 │
│ - fork()创建新进程 │
│ - 新进程调用ActivityThread.main() │
└────────────┬────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────┐
│ 应用进程B (新创建) │
│ 1. ActivityThread.main()启动 │
│ 2. 通过Binder通知ATMS: "我准备好了" │
│ 3. ATMS调用ApplicationThread.scheduleLaunchActivity() │
│ 4. ActivityThread通过Handler发送LAUNCH_ACTIVITY消息 │
│ 5. 创建Activity实例 │
│ 6. 依次调用: onCreate() → onStart() → onResume() │
│ 7. Activity界面显示 │
└─────────────────────────────────────────────────────────────┘
核心源码分析
1. startActivity入口(应用进程)
java
// frameworks/base/core/java/android/app/Activity.java
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// mParent通常为null(非嵌套Activity)
if (mParent == null) {
// 关键:通过Instrumentation启动Activity
// mMainThread.getApplicationThread()返回ApplicationThread(Binder Stub)
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, // 当前Activity上下文
mMainThread.getApplicationThread(), // ApplicationThread
mToken, // Activity的IBinder token
this, // 目标Activity
intent, // Intent
requestCode, // 请求码
options); // Bundle选项
} else {
// 嵌套Activity逻辑(已废弃)
}
}
关键点:
mInstrumentation: 应用进程的"代理人",负责与系统交互mMainThread.getApplicationThread(): 返回ApplicationThread,是AMS回调应用进程的Binder接口
2. Instrumentation跨进程调用(应用进程)
java
// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 获取ApplicationThread(Binder Stub)
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 关键:跨进程调用ATMS的startActivity
int result = ActivityTaskManager.getService().startActivity(
whoThread, // 应用进程的Binder接口
who.getBasePackageName(), // 调用者包名
who.getAttributionTag(),
intent, // Intent
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, // Activity token
target != null ? target.mEmbeddedID : null,
requestCode, // 请求码
0, // flags
null, // profilerInfo
options); // Bundle
// 检查启动结果,如果失败抛出异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
关键点:
ActivityTaskManager.getService(): 获取ATMS的Binder代理- 跨进程调用通过Binder完成,数据通过Parcel序列化传输
3. ATMS处理启动请求(SystemServer进程)
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
bOptions, UserHandle.getCallingUserId());
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
// 权限检查
enforceNotIsolatedCaller("startActivityAsUser");
// 检查调用者身份
userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
"startActivityAsUser", null);
// 关键:通过ActivityStarter处理启动
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute(); // 执行启动
}
4. ActivityStarter启动协调器(SystemServer进程)
ActivityStarter是Activity启动的核心协调器,负责:
- 解析Intent,找到目标Activity
- 检查权限和启动条件
- 决定创建新任务还是复用现有任务
- 协调进程创建(如果需要)
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
// 如果Intent包含多个Activity,批量启动
if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
// 核心启动逻辑
int res;
synchronized (mService.mGlobalLock) {
res = executeRequest(mRequest);
}
return res;
} finally {
onExecutionComplete();
}
}
private int executeRequest(Request request) {
// ...权限检查、Intent解析...
// 获取ActivityInfo(目标Activity的信息)
ActivityInfo aInfo = mSupervisor.resolveActivity(mRequest.intent, mRequest.resolvedType,
mRequest.startFlags, profilerInfo, mRequest.userId, mRequest.filterCallingUid);
// 检查目标Activity是否被禁用
if (aInfo != null) {
// 检查调用者是否有权限启动
// 检查目标Activity的exported属性
// 检查权限保护级别
}
// 关键:启动Activity
final ActivityRecord r = new ActivityRecord(...); // 创建ActivityRecord
mLastStartActivityRecord = r;
// 调用startActivityUnchecked继续处理
return startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor,
startFlags, true /* doResume */, checkedOptions, inTask, inTaskFragment,
balCode, intentGrants, restrictedBgActivity);
}
Activity启动的状态机
Activity启动过程是一个复杂的状态机,涉及多个状态转换:
scss
INITIALIZING (初始化)
↓
STARTED (已启动,等待进程)
↓
RESUMED (已恢复,前台显示)
↓
PAUSED (暂停,部分可见)
↓
STOPPED (停止,完全不可见)
↓
DESTROYED (已销毁)
Activity生命周期管理
生命周期回调顺序
Activity生命周期是Android开发者最熟悉的概念,但背后的实现机制涉及多个系统组件的协作。
scss
Activity A启动 → onCreate() → onStart() → onResume() (前台运行)
↓
点击Home键或打开新Activity
↓
Activity A暂停 → onPause() (仍可见,失去焦点)
↓
Activity A完全被覆盖
↓
Activity A停止 → onStop() (不可见)
↓
内存不足或用户主动销毁
↓
Activity A销毁 → onDestroy()
生命周期源码分析
1. onCreate()触发时机
java
// frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 1. 创建Activity实例
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
} catch (Exception e) {
// 处理异常
}
try {
// 2. 创建Application(如果还未创建)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 3. 初始化Activity上下文
Context appContext = createBaseContextForActivity(r);
// 4. attach Activity(关联Window、PhoneWindow等)
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken, r.shareableActivityToken);
// 5. 调用onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// 6. 调用onStart()
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
}
} catch (Exception e) {
// 处理异常
}
return activity;
}
2. onResume()触发时机
java
// frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
// 1. 执行onResume()回调
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r != null) {
final Activity a = r.activity;
// 2. 将Activity的DecorView添加到WindowManager
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE); // 先隐藏
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l); // 添加到WindowManager
} else {
a.onWindowAttributesChanged(l);
}
}
}
// 3. 让Activity可见
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible(); // 设置DecorView为VISIBLE
}
}
}
}
配置变更处理(Configuration Change)
当设备配置发生变化时(如屏幕旋转、语言切换、深色模式切换),Android默认会销毁并重建Activity。
java
// frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleConfigurationChanged(Configuration config, int displayId) {
// 更新Application的配置
if (mApplication != null) {
mApplication.onConfigurationChanged(config);
}
// 通知所有Activity配置变更
synchronized (mResourcesManager) {
// 遍历所有ActivityClientRecord
for (int i = mActivities.size() - 1; i >= 0; i--) {
ActivityClientRecord r = mActivities.valueAt(i);
if (r.activity != null) {
// 如果Activity声明了configChanges,调用onConfigurationChanged
// 否则销毁重建Activity
if ((r.activityInfo.configChanges & ActivityInfo.CONFIG_ORIENTATION) == 0) {
// 未声明configChanges,需要重启Activity
scheduleRelaunchActivity(r.token);
} else {
// 已声明configChanges,只回调onConfigurationChanged
r.activity.onConfigurationChanged(config);
}
}
}
}
}
如何避免重建 :在AndroidManifest.xml中声明android:configChanges:
xml
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden" />
进程优先级管理:OOM Adj机制
什么是OOM Adj?
OOM Adj(Out-Of-Memory Adjustment) 是Android进程优先级的核心机制,用于决定:
- 哪些进程可以获得更多CPU资源
- 内存不足时优先杀掉哪些进程
- 后台限制策略(如网络访问、定位服务)
Adj值越低,优先级越高,越不容易被杀死。
Adj值定义
java
// frameworks/base/services/core/java/com/android/server/am/ProcessList.java
public final class ProcessList {
// 最高优先级(Native守护进程)
static final int NATIVE_ADJ = -1000;
// 系统进程(SystemServer)
static final int SYSTEM_ADJ = -900;
// 持久化进程(system/persistent应用)
static final int PERSISTENT_PROC_ADJ = -800;
// 持久化服务进程
static final int PERSISTENT_SERVICE_ADJ = -700;
// 前台进程(用户正在交互)
static final int FOREGROUND_APP_ADJ = 0;
// 可见进程(Activity可见但不在前台)
static final int VISIBLE_APP_ADJ = 100;
// 可感知进程(Activity部分可见,如悬浮窗)
static final int PERCEPTIBLE_APP_ADJ = 200;
// 备份进程
static final int BACKUP_APP_ADJ = 300;
// 服务进程(后台Service)
static final int SERVICE_ADJ = 500;
// Home进程(Launcher)
static final int HOME_APP_ADJ = 600;
// 上一个可见进程(按Back键回到后台)
static final int PREVIOUS_APP_ADJ = 700;
// 缓存进程(最低优先级)
static final int CACHED_APP_MIN_ADJ = 900;
static final int CACHED_APP_MAX_ADJ = 999;
}
OOM Adj调整时机
AMS会在以下场景触发adj值重新计算:
java
// frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
void updateOomAdjLocked(String oomAdjReason) {
final long now = SystemClock.uptimeMillis();
final long oldTime = now - mConstants.MAX_EMPTY_TIME; // 30分钟
// 1. 遍历所有进程
for (int i = mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcessList.mLruProcesses.get(i);
// 2. 计算新的adj值
final int prevAppAdj = app.mState.getCurAdj();
final int prevProcState = app.mState.getCurProcState();
computeOomAdjLocked(app, cachedAdj, topApp, now, oomAdjReason, true);
// 3. 如果adj值或procState变化,应用新值
if (app.mState.getCurAdj() != prevAppAdj
|| app.mState.getCurProcState() != prevProcState) {
applyOomAdjLocked(app, true, now, SystemClock.elapsedRealtime());
}
}
}
触发时机:
- ✅ Activity启动/切换
- ✅ Service启动/绑定/解绑
- ✅ Broadcast发送/接收
- ✅ ContentProvider查询
- ✅ 进程启动/死亡
- ✅ 内存压力变化
Adj值计算逻辑
java
// frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
private boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, long now, String oomAdjReason, boolean doingAll) {
// 1. 如果是前台进程,直接设置为FOREGROUND_APP_ADJ
if (app == topApp && app.hasTopUi()) {
app.mState.setCurAdj(ProcessList.FOREGROUND_APP_ADJ);
app.mState.setCurProcState(PROCESS_STATE_TOP);
return true;
}
// 2. 如果有前台Service,设置为PERCEPTIBLE_APP_ADJ
if (app.mServices.hasForegroundServices()) {
app.mState.setCurAdj(ProcessList.PERCEPTIBLE_APP_ADJ);
app.mState.setCurProcState(PROCESS_STATE_FOREGROUND_SERVICE);
return true;
}
// 3. 如果有可见Activity,设置为VISIBLE_APP_ADJ
if (app.hasVisibleActivities()) {
app.mState.setCurAdj(ProcessList.VISIBLE_APP_ADJ);
app.mState.setCurProcState(PROCESS_STATE_TOP);
return true;
}
// 4. 如果有Service被前台进程绑定,提升优先级
for (int is = app.mServices.numberOfRunningServices() - 1; is >= 0; is--) {
ServiceRecord sr = app.mServices.getRunningServiceAt(is);
if (sr.connections.size() > 0) {
for (int conni = sr.connections.size() - 1; conni >= 0; conni--) {
ConnectionRecord cr = sr.connections.valueAt(conni);
if (cr.binding.client == topApp) {
// 被前台应用绑定的Service,提升为VISIBLE_APP_ADJ
app.mState.setCurAdj(ProcessList.VISIBLE_APP_ADJ);
return true;
}
}
}
}
// 5. 如果是缓存进程,设置为CACHED_APP_ADJ
app.mState.setCurAdj(cachedAdj);
app.mState.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
return true;
}
Low Memory Killer (LMK)
LMK工作原理
当系统内存不足时,Low Memory Killer(LMK) 会根据adj值杀掉低优先级进程来释放内存。
makefile
内存压力级别:
Critical (严重) → 杀掉adj >= 900的进程(缓存进程)
Moderate (中等) → 杀掉adj >= 700的进程(上一个应用)
Low (轻微) → 杀掉adj >= 800的进程(部分缓存进程)
LMK的实现演进
| Android版本 | LMK实现 | 说明 |
|---|---|---|
| Android 1.0-9 | Kernel LMK | 内核驱动,根据adj值杀进程 |
| Android 10-11 | lmkd守护进程 | 用户空间守护进程,更灵活 |
| Android 12+ | lmkd+PSI | 结合PSI(Pressure Stall Information)预测内存压力 |
lmkd守护进程
cpp
// system/core/lmkd/lmkd.cpp
static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_params) {
// 读取PSI内存压力信息
int64_t mem_usage = get_memory_usage(&mem_st);
// 根据内存压力等级决定杀掉哪些进程
if (mem_usage > critical_threshold) {
// 严重内存压力,杀掉adj >= 900的进程
kill_processes(CACHED_APP_MIN_ADJ, "critical");
} else if (mem_usage > moderate_threshold) {
// 中等内存压力,杀掉adj >= 800的进程
kill_processes(PREVIOUS_APP_ADJ, "moderate");
}
}
static int kill_processes(int min_oom_adj, const char* reason) {
// 从AMS获取进程列表
std::vector<ProcessRecord> procs = get_process_list();
// 按adj值排序(从高到低)
std::sort(procs.begin(), procs.end(),
[](const ProcessRecord& a, const ProcessRecord& b) {
return a.oom_adj > b.oom_adj;
});
// 杀掉adj值 >= min_oom_adj的进程
for (const auto& proc : procs) {
if (proc.oom_adj >= min_oom_adj) {
kill(proc.pid, SIGKILL);
ALOGI("Killed %s (pid %d, adj %d) reason: %s",
proc.process_name, proc.pid, proc.oom_adj, reason);
break; // 杀一个进程后重新评估内存
}
}
}
查看进程adj值
bash
# 查看所有进程的adj值
adb shell "cat /proc/$(adb shell pidof com.android.systemui | tr -d '\r')/oom_score_adj"
# 输出: 0 (FOREGROUND_APP_ADJ,前台应用)
# 查看进程详细信息
adb shell dumpsys activity processes | grep -A 10 "com.example.app"
Service与Broadcast管理
Service启动流程
Service有两种启动方式:
- startService(): 独立运行,不与调用者绑定
- bindService(): 绑定运行,随调用者生命周期
java
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service,
String resolvedType, int callingPid, int callingUid, boolean fgRequired,
String callingPackage, final int userId) {
// 1. 解析Intent,找到目标Service
ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType,
callingPackage, callingPid, callingUid, userId, true, callerFg, false, false);
ServiceRecord r = res.record;
// 2. 检查是否需要创建进程
if (r.app == null || r.app.getThread() == null) {
// 进程不存在,通知AMS创建进程
app = mAm.getProcessRecordLocked(processName, r.appInfo.uid);
if (app == null || app.getThread() == null) {
app = mAm.startProcessLocked(processName, r.appInfo, true, 0,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, false);
}
}
// 3. 调用Service的onCreate()
realStartServiceLocked(r, app, execInFg);
}
Broadcast发送流程
Broadcast分为两种:
- 普通广播: 异步发送,所有接收者并行接收
- 有序广播: 按优先级顺序发送,可以被拦截
java
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
// 1. 权限检查
enforceNotIsolatedCaller("broadcastIntent");
// 2. 查找所有匹配的Receiver
List<ResolveInfo> receivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, userId);
// 3. 创建BroadcastRecord
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId, false);
// 4. 加入广播队列
final BroadcastQueue queue = broadcastQueueForIntent(intent);
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
任务栈管理(Task Stack)
任务栈的概念
Task(任务) 是一组相关Activity的集合,以栈的形式组织(后进先出,LIFO)。
scss
┌─────────────────────────┐
│ Task 1 (前台任务) │
│ ┌───────────────────┐ │
│ │ Activity C (栈顶) │ │ ← 用户看到的界面
│ ├───────────────────┤ │
│ │ Activity B │ │
│ ├───────────────────┤ │
│ │ Activity A (栈底) │ │
│ └───────────────────┘ │
└─────────────────────────┘
┌─────────────────────────┐
│ Task 2 (后台任务) │
│ ┌───────────────────┐ │
│ │ Activity X (栈顶) │ │
│ ├───────────────────┤ │
│ │ Activity Y │ │
│ └───────────────────┘ │
└─────────────────────────┘
启动模式(Launch Mode)
Android提供4种启动模式,控制Activity的实例化和栈行为:
| 启动模式 | 行为 | 使用场景 |
|---|---|---|
| standard | 每次都创建新实例,可以有多个实例 | 普通Activity(默认) |
| singleTop | 如果栈顶是该Activity,复用;否则创建新实例 | 通知点击跳转、搜索结果页 |
| singleTask | 全局唯一实例,存在则清空其上的Activity | 应用主页(MainActivity) |
| singleInstance | 全局唯一实例,且独占一个Task | 来电界面、闹钟响铃 |
启动模式源码实现
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, NeededUriGrants intentGrants,
BackgroundActivityStartController balController) {
// 1. 根据LaunchMode决定是否复用Activity
final int launchMode = r.launchMode;
if (launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
// singleTop模式:检查栈顶
if (mTargetRootTask.getTopNonFinishingActivity() == r) {
// 栈顶就是该Activity,复用,调用onNewIntent()
deliverNewIntent(r, intentGrants);
return START_DELIVERED_TO_TOP;
}
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
|| launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// singleTask/singleInstance:查找已存在的实例
ActivityRecord intentActivity = mRootWindowContainer.findTask(r, options);
if (intentActivity != null) {
// 找到已存在的实例,清空其上的Activity
intentActivity.getTask().performClearTaskForReuse(true);
deliverNewIntent(intentActivity, intentGrants);
return START_TASK_TO_FRONT;
}
}
// 2. 没有复用,创建新实例
mTargetRootTask.startActivityLocked(r, topRootTask, newTask, isTaskSwitch, options,
intentGrants);
return START_SUCCESS;
}
ANR(Application Not Responding)
ANR触发条件
ANR是Android保护用户体验的机制,当应用在主线程阻塞太久时,系统会弹出"应用无响应"对话框。
| 场景 | 超时时间 | 说明 |
|---|---|---|
| Input事件 | 5秒 | 触摸/按键事件未处理完 |
| BroadcastReceiver | 10秒(前台) / 60秒(后台) | onReceive()未执行完 |
| Service | 20秒(前台) / 200秒(后台) | onCreate/onStartCommand未执行完 |
| ContentProvider | 10秒 | ContentProvider启动超时 |
ANR检测机制
java
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
void appNotResponding(ProcessRecord app, String activityShortComponentName,
ApplicationInfo aInfo, String parentShortComponentName,
WindowProcessController parentProcess, boolean aboveSystem, String annotation,
boolean onlyDumpSelf) {
synchronized (this) {
// 1. 检查是否已在ANR
if (app.isNotResponding()) {
Slog.i(TAG, "Skipping duplicate ANR: " + app);
return;
}
// 2. 标记为ANR状态
app.setNotResponding(true);
// 3. 收集ANR信息
StringBuilder info = new StringBuilder();
info.append("ANR in ").append(app.processName);
if (activityShortComponentName != null) {
info.append(" (").append(activityShortComponentName).append(")");
}
info.append("\n");
info.append("PID: ").append(app.getPid()).append("\n");
if (annotation != null) {
info.append("Reason: ").append(annotation).append("\n");
}
// 4. dump堆栈信息到/data/anr/traces.txt
final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
final File tracesFile = ActivityManagerService.dumpStackTraces(
app, processCpuTracker, null, null, null);
// 5. 显示ANR对话框或直接杀掉进程
Message msg = Message.obtain();
msg.what = SHOW_NOT_RESPONDING_UI_MSG;
msg.obj = new AppNotRespondingDialog.Data(app, aInfo, aboveSystem);
mUiHandler.sendMessage(msg);
}
}
ANR日志分析
ANR发生时,系统会生成日志:
bash
# 查看ANR日志
adb shell cat /data/anr/traces.txt
# 示例输出
----- pid 12345 at 2026-02-10 10:30:15 -----
Cmd line: com.example.app
suspend all histogram: Sum: 245us 99% C.I. 0.500us-110.500us Avg: 35us Max: 110us
DALVIK THREADS (23):
"main" prio=5 tid=1 Sleeping
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x75a0d0a0 self=0x7f8c4a4000
| sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7f8c4a4000
| state=S schedstat=( 1234567890 0 1234 ) utm=100 stm=23 core=2 HZ=100
| stack=0x7ff0000000-0x7ff0002000 stackSize=8192KB
| held mutexes=
at java.lang.Thread.sleep(Native method)
at com.example.app.MainActivity.onCreate(MainActivity.java:42) # 阻塞位置
at android.app.Activity.performCreate(Activity.java:8000)
...
Android 15的AMS优化
1. 启动性能优化
Android 15对Activity启动流程进行了多项优化:
- 并行化Intent解析: Intent解析与进程创建并行执行,减少等待时间
- 预测性进程预创建: 根据用户使用习惯,提前预创建进程
- 减少Binder调用次数: 合并多个小的Binder调用为批量调用
java
// Android 15新增: 批量启动多个Activity
public int startActivities(IApplicationThread caller, String callingPackage,
Intent[] intents, String[] resolvedTypes, IBinder resultTo,
Bundle options, int userId) {
// 批量处理,减少Binder往返次数
for (int i = 0; i < intents.length; i++) {
// ...
}
}
2. 内存管理优化
- Smart LMK: 结合机器学习预测应用使用频率,优先保留高频应用
- 进程冻结(Process Freezing): 后台进程冻结而非杀掉,恢复更快
- Compaction优化: 内存压缩技术,减少物理内存占用
3. 后台限制增强
- 更严格的后台Service限制: 后台Service启动超时从200秒降低到100秒
- JobScheduler优先: 推荐使用JobScheduler替代后台Service
- 前台Service通知: 前台Service必须显示持久通知
常见问题(FAQ)
Q1: AMS和ATMS有什么区别?
A: Android 10之前只有AMS,负责所有应用管理。Android 10重构后:
- ATMS: 管理Activity任务、栈、生命周期
- AMS: 管理进程、Service、Broadcast、OOM Adj
两者通过ActivityManagerInternal和ActivityTaskManagerInternal接口通信。
Q2: 为什么Home键不会触发onDestroy()?
A: 按Home键只是让Activity进入后台(onPause → onStop),进程和Activity实例仍保留在内存中,以便快速恢复。只有内存不足或主动finish()才会触发onDestroy()。
Q3: singleTask和singleInstance有什么区别?
A:
- singleTask: 全局唯一,但可以和其他Activity共享一个Task
- singleInstance : 全局唯一,且独占一个Task,该Task中只有这一个Activity
Q4: 为什么后台进程会被杀掉?
A: Android通过LMK机制管理内存,当内存不足时,会根据OOM Adj值杀掉低优先级进程。缓存进程(adj=900-999)最容易被杀,前台进程(adj=0)几乎不会被杀。
Q5: 如何避免ANR?
A:
- ✅ 耗时操作放到子线程(网络请求、数据库查询、文件IO)
- ✅ BroadcastReceiver的onReceive()不要超过10秒
- ✅ 使用Handler、AsyncTask、WorkManager处理异步任务
- ✅ 避免在主线程做复杂计算
Q6: 如何监控应用的adj值?
bash
# 查看当前adj值
adb shell cat /proc/$(adb shell pidof com.example.app | tr -d '\r')/oom_score_adj
# 持续监控adj变化
adb shell "while true; do cat /proc/\$(pidof com.example.app)/oom_score_adj; sleep 1; done"
Q7: Activity启动为什么要经过这么多步骤?
A: Activity启动涉及多个进程协作:
- Launcher进程: 发起启动请求
- SystemServer进程: ATMS处理Intent、AMS创建进程
- Zygote进程: fork新进程
- 应用进程: 初始化Activity
这样设计是为了:
- ✅ 安全隔离(权限检查)
- ✅ 进程复用(已有进程直接启动)
- ✅ 资源管理(统一管理生命周期)
实战:分析Activity启动性能
使用Systrace分析
bash
# 1. 启动Systrace追踪
adb shell am start -W -n com.example.app/.MainActivity --start-profiler
# 2. 捕获启动trace
python systrace.py -o trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res -t 10
# 3. 在Chrome中打开trace.html,查找关键阶段:
# - ActivityManager: startActivityAsUser
# - Zygote: fork进程
# - ActivityThread: handleLaunchActivity
# - Activity: onCreate/onStart/onResume
查看启动时间
bash
# 启动Activity并测量时间
adb shell am start -W -n com.example.app/.MainActivity
# 输出:
# Starting: Intent { cmp=com.example.app/.MainActivity }
# Status: ok
# LaunchState: COLD # COLD(冷启动)/WARM(温启动)/HOT(热启动)
# Activity: com.example.app/.MainActivity
# TotalTime: 432 # 总启动时间(ms)
# WaitTime: 445 # 包含系统开销的时间(ms)
# Complete
优化建议
-
减少onCreate()耗时:
- 延迟初始化(Lazy Initialization)
- 异步加载资源
- 避免同步网络请求
-
优化Application.onCreate():
- 第三方SDK初始化放到子线程
- 使用ContentProvider懒加载
-
减少布局层级:
- 使用ConstraintLayout
- 避免过深的嵌套
-
启用硬件加速:
xml<application android:hardwareAccelerated="true"> </application>
总结
本文深度剖析了AMS和ATMS的核心机制:
核心要点回顾
-
AMS与ATMS分工:
- ATMS负责Activity任务管理(启动、栈、生命周期)
- AMS负责进程管理(创建、优先级、回收)
-
Activity启动流程:
- 应用进程(Launcher) → ATMS → AMS → Zygote → 新应用进程
- 涉及Binder IPC、Socket通信、进程fork
-
生命周期管理:
- onCreate → onStart → onResume → onPause → onStop → onDestroy
- 配置变更默认会重建Activity,可通过configChanges避免
-
进程优先级(OOM Adj):
- 前台进程(adj=0)最高,缓存进程(adj=900-999)最低
- 动态调整,影响CPU资源和内存回收
-
Low Memory Killer:
- 内存不足时根据adj值杀进程
- lmkd守护进程+PSI(压力检测)
-
任务栈管理:
- Task是Activity的栈结构
- 4种启动模式: standard/singleTop/singleTask/singleInstance
-
ANR机制:
- Input事件5秒、Broadcast 10秒、Service 20秒超时触发
- 主线程不要做耗时操作
参考资料
- Android官方文档 - 进程和应用生命周期
- AOSP 15.0源码 - ActivityManagerService.java
- AOSP 15.0源码 - ActivityTaskManagerService.java
- Android Developers Blog - 进程管理优化
系列文章
本文基于Android 15 (API Level 35)源码分析,不同厂商的定制ROM可能存在差异。 欢迎来我中的个人主页找到更多有用的知识和有趣的产品