AMS核心机制:Activity生命周期与进程管理深度解析

0 阅读14分钟

引言

在上一篇文章中,我们见证了Zygote如何"孵化"应用进程,但进程诞生后的生命历程由谁来管理?Activity如何启动?进程优先级如何决定?内存不足时哪个进程会被杀掉?

这一切的答案都指向ActivityManagerService(AMS)——Android系统中最核心、最复杂的系统服务之一。

想象这样一个场景:你同时打开了微信、Chrome和抖音,切换应用时系统秒开,内存吃紧时后台应用自动被杀掉却不影响前台体验。这背后的"指挥官"就是AMS

你点击应用图标
    ↓
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管理
ATMSActivity任务管理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的协作关系,下图展示了完整的架构:

14-01-ams-atms-architecture.png

图:AMS与ATMS分工协作,ATMS负责Activity任务管理,AMS负责进程与生命周期管理,两者通过ActivityManagerInternal/ActivityTaskManagerInternal接口通信

这张图涵盖了:

  • 应用层: App进程通过Binder调用AMS/ATMS
  • ATMS层: Activity启动、栈管理、生命周期
  • AMS层: 进程管理、OOM Adj、Service/Broadcast
  • 底层协作: Zygote进程创建、WMS窗口管理、LMK内存回收

接下来,我们将逐一深入这些核心机制的源码实现。


Activity启动流程深度解析

启动流程全景

Activity启动涉及多个进程和系统服务的协作,是Android中最复杂的流程之一。

┌─────────────────────────────────────────────────────────────┐
│  应用进程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入口(应用进程)

// 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跨进程调用(应用进程)

// 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进程)

// 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
  • 检查权限和启动条件
  • 决定创建新任务还是复用现有任务
  • 协调进程创建(如果需要)
// 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启动过程是一个复杂的状态机,涉及多个状态转换:

INITIALIZING (初始化)
    ↓
STARTED (已启动,等待进程)
    ↓
RESUMED (已恢复,前台显示)
    ↓
PAUSED (暂停,部分可见)
    ↓
STOPPED (停止,完全不可见)
    ↓
DESTROYED (已销毁)

Activity生命周期管理

生命周期回调顺序

Activity生命周期是Android开发者最熟悉的概念,但背后的实现机制涉及多个系统组件的协作。

Activity A启动    → onCreate() → onStart() → onResume() (前台运行)
                     ↓
点击Home键或打开新Activity
                     ↓
Activity A暂停    → onPause() (仍可见,失去焦点)
                     ↓
Activity A完全被覆盖
                     ↓
Activity A停止    → onStop() (不可见)
                     ↓
内存不足或用户主动销毁
                     ↓
Activity A销毁    → onDestroy()

生命周期源码分析

1. onCreate()触发时机

// 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()触发时机

// 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

// 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:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize|keyboardHidden" />

进程优先级管理:OOM Adj机制

什么是OOM Adj?

OOM Adj(Out-Of-Memory Adjustment) 是Android进程优先级的核心机制,用于决定:

  • 哪些进程可以获得更多CPU资源
  • 内存不足时优先杀掉哪些进程
  • 后台限制策略(如网络访问、定位服务)

Adj值越低,优先级越高,越不容易被杀死。

Adj值定义

// 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值重新计算:

// 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值计算逻辑

// 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值杀掉低优先级进程来释放内存。

内存压力级别:
Critical (严重) → 杀掉adj >= 900的进程(缓存进程)
Moderate (中等) → 杀掉adj >= 700的进程(上一个应用)
Low (轻微)      → 杀掉adj >= 800的进程(部分缓存进程)

LMK的实现演进

Android版本LMK实现说明
Android 1.0-9Kernel LMK内核驱动,根据adj值杀进程
Android 10-11lmkd守护进程用户空间守护进程,更灵活
Android 12+lmkd+PSI结合PSI(Pressure Stall Information)预测内存压力

lmkd守护进程

// 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值

# 查看所有进程的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(): 绑定运行,随调用者生命周期
// 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分为两种:

  • 普通广播: 异步发送,所有接收者并行接收
  • 有序广播: 按优先级顺序发送,可以被拦截
// 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)。

┌─────────────────────────┐
│  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来电界面、闹钟响铃

启动模式源码实现

// 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秒触摸/按键事件未处理完
BroadcastReceiver10秒(前台) / 60秒(后台)onReceive()未执行完
Service20秒(前台) / 200秒(后台)onCreate/onStartCommand未执行完
ContentProvider10秒ContentProvider启动超时

ANR检测机制

// 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发生时,系统会生成日志:

# 查看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调用为批量调用
// 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

两者通过ActivityManagerInternalActivityTaskManagerInternal接口通信。

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值?

# 查看当前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分析

# 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

查看启动时间

# 启动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

优化建议

  1. 减少onCreate()耗时:

    • 延迟初始化(Lazy Initialization)
    • 异步加载资源
    • 避免同步网络请求
  2. 优化Application.onCreate():

    • 第三方SDK初始化放到子线程
    • 使用ContentProvider懒加载
  3. 减少布局层级:

    • 使用ConstraintLayout
    • 避免过深的嵌套
  4. 启用硬件加速:

    <application
        android:hardwareAccelerated="true">
    </application>
    

总结

本文深度剖析了AMS和ATMS的核心机制:

核心要点回顾

  1. AMS与ATMS分工:

    • ATMS负责Activity任务管理(启动、栈、生命周期)
    • AMS负责进程管理(创建、优先级、回收)
  2. Activity启动流程:

    • 应用进程(Launcher) → ATMS → AMS → Zygote → 新应用进程
    • 涉及Binder IPC、Socket通信、进程fork
  3. 生命周期管理:

    • onCreate → onStart → onResume → onPause → onStop → onDestroy
    • 配置变更默认会重建Activity,可通过configChanges避免
  4. 进程优先级(OOM Adj):

    • 前台进程(adj=0)最高,缓存进程(adj=900-999)最低
    • 动态调整,影响CPU资源和内存回收
  5. Low Memory Killer:

    • 内存不足时根据adj值杀进程
    • lmkd守护进程+PSI(压力检测)
  6. 任务栈管理:

    • Task是Activity的栈结构
    • 4种启动模式: standard/singleTop/singleTask/singleInstance
  7. ANR机制:

    • Input事件5秒、Broadcast 10秒、Service 20秒超时触发
    • 主线程不要做耗时操作

参考资料

  1. Android官方文档 - 进程和应用生命周期
  2. AOSP 15.0源码 - ActivityManagerService.java
  3. AOSP 15.0源码 - ActivityTaskManagerService.java
  4. Android Developers Blog - 进程管理优化

系列文章


本文基于Android 15 (API Level 35)源码分析,不同厂商的定制ROM可能存在差异。 欢迎来我中的个人主页找到更多有用的知识和有趣的产品