Android Framework源码解析(十):Service启动全流程——从startService到Service执行的源码深度解析

一、前文回顾 & 本章目标

上一篇文章完整拆解了 App 进程诞生全流程,从ATMS.startProcessAsync() 一路追踪到 Zygote 进程,打通了 Android 应用进程的底层启动逻辑,同时明确了一个核心认知:Activity 并非 Android 应用唯一核心组件

Activity 负责前台界面展示,而 Service 专注于无界面后台任务处理,是 Android 四大组件中后台能力的核心载体,广泛应用于音乐后台播放、持续位置监听、跨进程服务常驻、后台数据同步等场景。

日常开发中,我们仅需一行代码即可启动服务

java 复制代码
Intent intent = new Intent(this, MyService.class);
startService(intent);

但这行简单代码的背后,隐藏着 Framework 多层跨进程调度、进程创建、组件生命周期回调的完整逻辑。本文将逐层拆解整条源码链路,打通从应用层调用到 Service 真正执行的全流程,同时补齐停止流程、核心原理与面试高频考点。

全文将围绕 应用发起请求 → system_server 系统调度 → 进程创建/绑定 → Service 实例初始化 → 生命周期回调 → 服务销毁 主线展开,彻底讲透 startService 底层机制。

二、Service 启动流程总览

1. 整体调用链

完整主线调用链路(贯穿全文核心):

bash 复制代码
Context.startService()
→ ContextWrapper.startService()
→ ContextImpl.startServiceCommon()
→ AMS.startService()
→ ActiveServices.startServiceLocked()
→ retrieveServiceLocked()
→ startServiceInnerLocked()
→ bringUpServiceLocked()
→ startProcessLocked()(进程不存在时)
→ Zygote 创建 App 进程
→ ActivityThread.main()
→ ActivityThread.attach()
→ AMS.attachApplication()
→ AMS.attachApplicationLocked()
→ realStartServiceLocked()
→ scheduleCreateService()
→ handleCreateService()
→ Service.onCreate()
→ sendServiceArgsLocked()
→ scheduleServiceArgs()
→ handleServiceArgs()
→ Service.onStartCommand()

停止流程链路:

bash 复制代码
Context.stopService()
→ ContextWrapper.stopService()
→ ContextImpl.stopServiceCommon()
→ AMS.stopService()
→ ActiveServices.stopServiceLocked()
→ bringDownServiceLocked()
→ scheduleStopService()
→ ActivityThread.handleStopService()
→ Service.onDestroy()

2. 两次核心 Binder 通信

整个启动流程横跨 App 进程、system_server 进程,依靠两次关键 Binder 跨进程通信完成调度:

  • 第一次 Binder:App 进程 → system_server 进程 ContextImpl 通过 IActivityManager 接口,将服务启动请求提交至 AMS,完成应用层到系统服务层的请求上报、参数传递与权限校验。

  • 第二次 Binder:system_server 进程 → App 进程 AMS/ActiveServices 通过 IApplicationThread 接口,反向通知目标 App 进程完成 Service 实例创建、生命周期回调与参数投递。

3. 三种启动场景

系统根据目标服务与进程运行状态,分为三种启动场景,对应不同执行链路:

  • 场景一:Service 已正常运行:仅投递启动参数,重复触发 onStartCommand(),不重建实例、不执行 onCreate()

  • 场景二:App 进程存在、Service 未创建:直接创建 Service 实例,回调完整生命周期

  • 场景三:App 进程不存在:先 fork 新 App 进程,再初始化并启动 Service(最完整全流程)

三、应用层:Context.startService() 入口流程

1. ContextWrapper 方法转发机制

startService() 是 Context 的抽象方法,上层 Activity、Service、Application 调用均无直接实现,全部依托包装类转发。

核心继承关系:

  • Activity → ContextThemeWrapper → ContextWrapper → Context

  • Service → ContextWrapper → Context

  • Application → ContextWrapper → Context

ContextWrapper 仅做方法转发,无核心逻辑,源码如下:

java 复制代码
public @Nullable ComponentName startService(Intent service) {
    return mBase.startService(service);
}

其中 mBase 真实实例为 ContextImpl,所有核心逻辑均由 ContextImpl 实现。

2. ContextImpl.startServiceCommon() 核心预处理

源码位置:core/java/android/app/ContextImpl.java

ContextImpl 的 startService 方法为真正入口,区分前台/后台服务启动:

java 复制代码
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser);
}

public ComponentName startForegroundService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, true, mUser);
}

参数区分:

  • startService() → requireForeground = false(普通后台服务)

  • startForegroundService() → requireForeground = true(前台服务)

核心统一处理方法 startServiceCommon:

java 复制代码
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
          UserHandle user) {
      try {
          validateServiceIntent(service);
          service.prepareToLeaveProcess(this);
          // 获取AMSBinder代理,发起首次跨进程调用
          IActivityManager am = ActivityManager.getService();
          ComponentName cn = am.startService(
                  mMainThread.getApplicationThread(), service,
                  service.resolveTypeIfNeeded(getContentResolver()),
                  requireForeground, getOpPackageName(), getAttributionTag(),
                  user.getIdentifier());
          ...
          return cn;
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }

ActivityManager.getService() 核心源码,这是应用层获取系统AMS代理的关键,所有组件系统调用均依托该代理:

java 复制代码
public static IActivityManager getService() {
    return IActivityManager.Stub.asInterface(ServiceManager.getService(Context.ACTIVITY_SERVICE));
}

原理:通过ServiceManager获取系统注册的AMSBinder服务,完成应用到system_server的跨进程通信绑定。

3. Intent 校验与首次 Binder 调用

该方法完成三大核心预处理,是应用层请求落地的关键:

(1)validateServiceIntent():Intent 合法性校验

Android 5.0(API21)起,targetSdkVersion≥21 强制要求显式 Intent 启动 Service,禁止隐式 Intent,规避安全风险与组件匹配混乱问题。

❌ 错误隐式写法:

java 复制代码
Intent intent = new Intent("com.example.TEST_SERVICE");
startService(intent);

✅ 正确显式写法:

java 复制代码
Intent intent = new Intent(this, MyService.class);
startService(intent);
(2)prepareToLeaveProcess():跨进程数据预处理

对 Intent 做跨进程适配,处理 URI 权限、ClipData 等数据,保证 Binder 传输完整性与合法性。

(3)Binder 跨进程调用 AMS

通过 ActivityManager.getService() 获取 IActivityManager Binder 代理,发起第一次跨进程调用,将请求上交 system_server 进程的 AMS,正式进入系统层调度逻辑。

同时区分关键知识点:startService 走 AMS,不走 ATMS。ATMS 仅负责 Activity、任务栈、窗口管理,与 Service 调度无关。补充两者核心区别,补齐删减的对比逻辑:

  • AMS(ActivityManagerService):核心管控四大组件生命周期、进程调度、Service/广播调度、ANR、后台权限限制

  • ATMS(ActivityTaskManagerService):Android10+拆分而出,仅专注Activity任务栈、窗口、页面跳转、后台页面管控,不参与Service任何流程

四、system_server:AMS → ActiveServices 系统层调度

1. AMS.startService() 系统入口

AMS 是 Android 组件与进程的核心总管,所有四大组件启动、进程调度、后台权限、ANR、OOM 管控均由 AMS 统一负责。系统开机时,AMS 会通过 setSystemProcess() 完成服务注册

java 复制代码
public void setSystemProcess() {
    try {
        // 将自身注册到ServiceManager,供全局应用调用
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        // 配置系统进程权限、UID、应用信息
        mProcessList.setSystemProcess();
        ...
    } catch (RemoteException e) {
        throw new RuntimeException(e);
    }
}

源码位置:services/core/java/com/android/server/am/ActivityManagerService.java

AMS startService 核心逻辑:做参数校验、调用方合法性校验、获取 PID/UID、加全局锁,最终转发至 ActiveServices。

java 复制代码
public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage,
            String callingFeatureId, int userId)
            throws TransactionTooLargeException {
        return startService(caller, service, resolvedType, requireForeground, callingPackage,
                callingFeatureId, userId, false /* isSdkSandboxService */, INVALID_UID, null, null);
    }

核心校验逻辑:禁止隔离进程调用、校验 Intent 无文件描述符、校验包名合法、记录调用方身份信息,保证系统调度安全。

2. ActiveServices.startServiceLocked() 核心分发

ActiveServices 是 system_server 中负责 Service 运行管理的核心类,主要承担 Service 的启动、停止、状态维护、进程关联、执行超时监控及后台启动限制等工作,并与 AMS、ProcessList 和 App 进程协同完成整个生命周期。

java 复制代码
ComponentName startServiceLocked(IApplicationThread caller,
        Intent service, String resolvedType,
        int callingPid, int callingUid,
        String callingPackage, String callingFeatureId,
        boolean fgRequired, boolean callerFg,
        boolean allowBackgroundActivityStarts,
        int userId, boolean useCallingUser) {

    ServiceLookupResult res = retrieveServiceLocked(
            service,
            resolvedType,
            callingPackage,
            callingPid,
            callingUid,
            userId,
            ...);

    if (res.record == null) {
        return res.permission;
    }

    ServiceRecord r = res.record;

    return startServiceInnerLocked(
            r,
            service,
            callingUid,
            fgRequired,
            callerFg,
            allowBackgroundActivityStarts,
            ...);
}

startServiceLocked 核心执行步骤:

  1. 校验应用前后台运行状态,拦截后台非法启动请求(Android8.0+核心限制)

  2. 调用 retrieveServiceLocked 解析服务信息、创建/获取 ServiceRecord

  3. 完成权限校验、前台服务规则校验

  4. 转发至 startServiceInnerLocked 封装启动请求

3. retrieveServiceLocked() 服务解析

该方法核心作用:根据 Intent 解析目标 Service 组件信息,校验组件是否在清单文件注册、校验应用权限、匹配用户ID,同时创建或复用系统侧的 ServiceRecord 对象,为后续调度提供数据支撑。

4. ServiceRecord 核心机制

ServiceRecord 是 system_server 中 Service 的状态镜像

在常规 Service 启动流程中,真实的 Service 实例运行在 App 进程,system_server 主要通过 ServiceRecord 保存服务的组件信息、进程关联、启动状态、绑定状态及调度信息。

系统所有的调度、限流、ANR 判断、后台限制,全部依赖 ServiceRecord 状态,是系统管控 Service 的核心数据载体。为方便理解,补充ServiceRecord 核心关键字段

  • service:对应开发者定义的Service组件信息(ComponentName)

  • app:绑定服务所在进程的ProcessRecord,记录进程运行状态

  • startRequested:标记是否为startService启动模式,区分bind绑定模式

  • pendingStarts:待执行的启动请求队列,存储多次startService的StartItem

  • isForeground:标记服务是否为前台服务,管控后台权限限制

  • destroyed:服务销毁标记,用于拦截无效调度

5. startServiceInnerLocked() 请求封装

该方法核心两大操作:

  • 标记启动模式r.startRequested = true,标记当前服务为 start 启动模式,区分 bind 绑定模式

  • 缓存启动请求 :每次启动请求通常会生成一个 StartItem,由系统根据当前 Service 状态决定立即投递或暂存到 pendingStarts,待 Service 创建完成后再统一处理。

这也是面试高频考点的底层原理:Service 实例唯一,onCreate 只执行一次;多次启动会缓存多个 StartItem,多次触发 onStartCommand

请求封装完成后,调用 bringUpServiceLocked() 进入服务唤醒核心逻辑。

五、Service 真正启动:bringUpServiceLocked() 场景分支处理

该方法是服务唤醒的核心分支入口,根据「进程+服务」运行状态,分流三种启动场景,覆盖所有启动情况。

1. 场景一:Service 已正常运行

服务实例、所在 App 进程均已存在且正常运行,无需重建实例与进程。系统直接调用 sendServiceArgsLocked(),将 pendingStarts 队列中的启动参数逐个投递,仅触发 onStartCommand() 回调。

2. 场景二:进程存在但 Service 未创建

App 进程已启动,但目标 Service 从未初始化。系统通过 ProcessRecord 匹配到对应进程,直接执行 realStartServiceLocked(),通过 Binder 通知目标进程创建 Service 实例,执行完整 onCreate + onStartCommand 流程。

3. 场景三:进程不存在(完整全流程)

无对应 App 进程,属于冷启动场景。系统将当前 Service 加入 mPendingServices 挂起队列,调用 startProcessLocked() 触发进程创建流程,等待新进程初始化完成后,再唤醒执行 Service 创建逻辑。

java 复制代码
if (r.app != null && r.app.thread != null) {
    // App 进程和 Service 实例都已经存在
    sendServiceArgsLocked(r, ...);
    return;
}

if (app != null && app.thread != null) {
    // App 进程存在,但 Service 尚未创建
    realStartServiceLocked(r, app, ...);
    return;
}

// App 进程不存在
if (app == null) {
    app = startProcessLocked(
            r.appInfo,
            serviceName,
            ...);
}

mPendingServices.add(r);

bringUpServiceLocked() 的核心并不是简单地"启动 Service",而是根据 ServiceRecord.appApplicationThread 以及 Service 实例状态,决定是直接投递启动参数、创建 Service,还是先启动 App 进程。

六、进程不存在:AMS → Zygote → App 进程创建

1. startProcessLocked() 进程启动准备

AMS 委托 ProcessList 完成进程参数组装,配置 UID、权限、应用入口、ABI、进程优先级等核心参数,校验应用启动权限,正式发起进程创建请求。

2. Zygote fork 新进程

通过 Process.start() 调用 ZygoteProcess,与 Zygote 进程 Socket 通信,Zygote 执行 fork 操作,生成全新的独立 App 进程,完成进程资源初始化与隔离。

3. ActivityThread.main() 进程入口

新 App 进程创建后,入口方法为 ActivityThread.main(),初始化主线程 Looper、Handler、ActivityThread 实例,搭建 App 主线程运行环境。

4. ActivityThread.attach() 绑定系统服务

App 进程初始化完成后,主动通过 Binder 调用 AMS.attachApplication(),将自身 ApplicationThread(App 端 Binder 服务)注册到 system_server。

AMS 收到注册请求后,执行 bindApplication 逻辑,完成 Application 初始化、ClassLoader 加载、组件环境初始化,保证 Service 创建前 Application 已完全就绪 。 下面通过 ActivityThread.attach() 核心源码,分析 App 进程如何向 AMS 注册自身:

java 复制代码
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    // 获取AMS代理
    IActivityManager mgr = ActivityManager.getService();
    try {
        // 向AMS注册当前应用进程的Binder通信端
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    // 初始化系统配置、资源管理器、权限校验器
    ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            if (!mSystemThread) {
                Resources.updateSystemConfiguration(newConfig, DisplayMetrics.DENSITY_DEVICE_STABLE);
            }
        }
        ...
    });
}

最后 AMS 遍历 mPendingServices 挂起队列,匹配当前新进程的待启动 Service,触发后续创建逻辑。

需要注意,ActivityThread.attach() 并不会直接创建 Service。它的作用是让新 App 进程通过 ApplicationThread 向 AMS 报到。AMS 收到进程注册后,才会从 mPendingServices 中找到等待启动的 Service,并调用 realStartServiceLocked(),随后通过 scheduleCreateService() 通知 App 进程真正创建 Service

七、Service 实例创建:realStartServiceLocked() 核心落地

1. 绑定 ProcessRecord 与 ServiceRecord

将系统侧的 ServiceRecord 与新创建的 App 进程 ProcessRecord 双向绑定,标记服务所属进程,完成进程与组件的关联,方便后续状态管理与销毁回收。

2. 开启 ANR 监控

调用 bumpServiceExecutingLocked() 启动服务执行超时计时,若主线程卡顿、未在规定时间内完成生命周期回调,将触发 Service ANR 异常。

3. scheduleCreateService() 跨进程通知创建

通过第二次 Binder 跨进程调用,调用 App 进程 ApplicationThread 的 scheduleCreateService 方法。该方法运行在 Binder 线程,不会直接创建组件,而是发送 H.CREATE_SERVICE 消息,将任务切换至主线程。

java 复制代码
r.app = app;

bumpServiceExecutingLocked(
        r,
        execInFg,
        "create");

app.thread.scheduleCreateService(
        r,
        r.serviceInfo,
        r.compat,
        ...);

4. handleCreateService() 反射创建实例

主线程处理创建消息,是App 进程创建 Service 实例的 核心入口,核心流程:

  1. 获取当前应用 LoadedApk 与 ClassLoader

  2. 复用/初始化 Application 实例

  3. 反射实例化目标 Service

  4. 创建 Service 专属 ContextImpl 上下文

  5. 执行 service.attach() 绑定运行环境

java 复制代码
LoadedApk packageInfo = getPackageInfoNoCheck(
        data.info.applicationInfo,
        data.compatInfo);

Service service = packageInfo.getAppFactory()
        .instantiateService(
                cl,
                data.info.name,
                data.intent);

ContextImpl context = ContextImpl.createAppContext(
        this,
        packageInfo);

context.setOuterContext(service);

service.attach(
        context,
        this,
        data.info.name,
        data.token,
        app,
        ActivityManager.getService());

service.onCreate();

mServices.put(data.token, service);

解释:

  1. LoadedApk 提供应用运行环境;

  2. ClassLoader 加载目标 Service 类;

  3. instantiateService() 通过反射创建真实实例;

  4. ContextImpl 为 Service 创建上下文;

  5. attach() 绑定运行环境;

  6. onCreate() 执行开发者初始化逻辑;

  7. mServices 保存 Service 实例,供后续启动参数和停止流程查找。

5. Service.attach() 环境绑定

为 Service 绑定上下文、主线程、AMS 代理、应用配置等运行依赖,完成服务运行环境初始化,让 Service 具备独立运行、访问系统服务、处理任务的能力。

6. onCreate() 生命周期回调

环境绑定完成后,系统正式回调 Service.onCreate(),完成服务初始化。该方法全局仅执行一次,作为服务生命周期的起点。

创建完成后通知 AMS 结束 ANR 计时,缓存 Service 实例至 ActivityThread。

八、启动参数投递:onStartCommand() 任务处理

1. sendServiceArgsLocked() 准备启动参数

Service 实例创建完成后,ActiveServices 遍历 pendingStarts 队列中的所有 StartItem,封装每一次的启动 Intent、标记、startId,准备投递至 App 进程。

2. scheduleServiceArgs() 跨进程投递

通过 Binder 调用 scheduleServiceArgs,将批量启动参数发送至 App 进程,Binder 线程转发 H.SERVICE_ARGS 消息至主线程。

3. handleServiceArgs() 主线程处理

主线程接收消息,取出缓存的 Service 实例与启动参数,准备执行最终生命周期回调。

参数配置:

java 复制代码
while (r.pendingStarts.size() > 0) {
    StartItem si = r.pendingStarts.remove(0);

    args.add(new ServiceStartArgs(
            si.taskRemoved,
            si.id,
            si.flags,
            si.intent));
}

r.app.thread.scheduleServiceArgs(
        r,
        args,
        ...);

handleServiceArgs() 核心源码

java 复制代码
private void handleServiceArgs(ServiceArgsData data) {
    Service service = mServices.get(data.token);
    if (service != null) {
        try {
            // 回调业务核心方法
            int res = service.onStartCommand(data.args, data.flags, data.startId);
            // 告知AMS当前服务执行状态,更新重启策略
            ActivityManager.getService().serviceDoneExecuting(
                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, res);
        } catch (Exception e) {
            ...
        }
    }
}

4. onStartCommand() 业务逻辑回调

正式回调开发者自定义的 onStartCommand() 方法,处理每次启动携带的 Intent 参数,同时将返回值回传给 AMS,决定服务被杀后的重启策略。

onStartCommand 四大返回值策略:

|----------------------------|--------------------------------------|
| 返回值 | 核心含义 |
| START_STICKY | 服务被杀后,系统自动重建 Service,Intent 可能为 null |
| START_NOT_STICKY | 服务被杀后,无新启动请求则不重建 |
| START_REDELIVER_INTENT | 服务被杀重建后,重新投递最后一次启动 Intent |
| START_STICKY_COMPATIBILITY | 兼容旧版本,不保证强制重启 |

九、Service 停止全流程解析

1. stopService() 应用层入口

开发者调用 stopService(),经 ContextWrapper 转发至 ContextImpl,通过 stopServiceCommon 预处理后,Binder 跨进程调用 AMS.stopService()。

java 复制代码
// ContextWrapper 转发方法
public boolean stopService(Intent name) {
    return mBase.stopService(name);
}

// ContextImpl 核心实现
public boolean stopService(Intent service) {
    warnIfCallingFromSystemProcess();
    return stopServiceCommon(service, mUser);
}

private boolean stopServiceCommon(Intent service, UserHandle user) {
    try {
        validateServiceIntent(service);
        service.prepareToLeaveProcess(this);
        // Binder跨进程调用AMS停止服务
        return ActivityManager.getService().stopService(
                getOpPackageName(), service, service.resolveTypeIfNeeded(getContentResolver()),
                user.getIdentifier());
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

2. stopServiceLocked() 系统层处理

ActiveServices 接收停止请求,查询对应 ServiceRecord,取消服务启动标记 startRequested = false,同时校验服务当前状态:是否存在绑定连接、是否有待执行任务。

3. bringDownServiceLocked() 销毁判定

系统核心判定逻辑:

  • 若服务存在 bind 绑定连接:仅取消启动状态,不销毁服务

  • 当服务不存在其他需要保留的启动请求、绑定关系或相关运行状态时,系统才会进入真正的销毁流程。

4. scheduleStopService() 通知 App 进程

通过 Binder 跨进程通知 App 进程,发送 STOP_SERVICE 消息至主线程,触发 handleStopService 处理。

5. onDestroy() 最终销毁回调

主线程执行服务销毁逻辑,回调 Service.onDestroy(),清理服务资源、移除 ActivityThread 缓存,完成服务彻底销毁。

核心易错点:Service 无 onStop() 生命周期方法,停止服务唯一销毁回调为 onDestroy()

十、核心原理总结(面试高频)

1. ServiceRecord vs Service

  • Service:运行在 App 进程的真实实例,开发者可操作,执行业务逻辑与生命周期

  • ServiceRecord:运行在 system_server 的状态镜像,系统用于管控服务状态、调度、限流、ANR 判断,无业务逻辑

核心本质:系统管状态,应用管实例。

2. onCreate vs onStartCommand

  • onCreate():服务实例初始化方法,全局唯一,只执行一次,用于初始化资源

  • onStartCommand():单次启动请求回调,可多次执行,用于处理每次启动的 Intent 任务

  • 固定顺序:onCreate() 必然优先于 onStartCommand()

3. startService vs bindService

  • startService:关注后台任务常驻,独立运行,不受调用方生命周期影响,需主动 stopService 销毁

  • bindService:关注进程通信与绑定交互,依赖客户端连接,所有绑定断开后服务自动销毁

  • 混合场景:同时 start+bind 时,需 stopService + 全部 unbind 才能销毁服务

4. Service ANR 原理

系统在服务创建、参数投递阶段开启超时监控,若 App 主线程卡顿、耗时操作阻塞主线程,未及时完成生命周期回调、未调用 serviceDoneExecuting() 结束计时,就会触发 Service ANR。所有生命周期方法均运行在主线程,禁止耗时操作。

5. 后台启动限制原理

Android 8.0(API 26)引入后台执行限制。后台应用启动普通 Service 时可能受到限制并抛出 IllegalStateException,具体还要结合系统豁免规则、应用当前状态及前台服务启动条件判断。需要持续执行的后台任务通常应考虑前台服务或其他系统推荐机制。

十一、面试极简标准答案

1. 简述 startService 完整流程

应用调用 startService(),经 ContextWrapper 转发至 ContextImpl,完成 Intent 校验与跨进程预处理,通过 Binder 调用 AMS。AMS 交由 ActiveServices 完成服务解析、权限校验、后台限制拦截,创建 ServiceRecord 记录服务状态。若目标 App 进程不存在,AMS 触发 Zygote fork 新进程,进程初始化完成后向 AMS 报到。系统通过第二次 Binder 通知 App 进程,在主线程反射创建 Service 实例、回调 onCreate(),再投递启动参数,最终回调 onStartCommand() 处理业务逻辑。

2. onCreate 和 onStartCommand 核心区别

onCreate() 是服务实例初始化方法,全局仅执行一次,用于初始化服务资源;onStartCommand() 是单次启动请求的回调,多次调用 startService() 会多次触发,用于处理每一次启动携带的 Intent 参数与业务任务。

3. stopService 会不会触发 onStop()?

不会。Service 没有 onStop() 生命周期方法,在服务最终满足销毁条件时,系统会通过 handleStopService() 回调 onDestroy()。且服务存在绑定连接时,stopService 仅取消启动状态,不会立即销毁服务。

十二、结语

一行简单的 startService(),背后是 Android Framework 精心设计的跨进程调度、组件生命周期管理、进程资源管控机制。核心设计思想可总结为三点:

  1. 应用仅发起请求,不直接创建、管理组件,所有权限、状态、进程由系统统一管控;

  2. AMS + ActiveServices 双核心,实现 Service 全生命周期系统化调度;

  3. 组件实例化与生命周期执行下沉至应用进程,保证应用隔离性与独立性。

该设计也是 Android 四大组件的统一核心思想:应用请求 → 系统调度 → 目标进程执行,理解 Service 启动流程,可快速举一反三掌握 Activity、广播的底层启动原理。

相关推荐
换元不配限2 小时前
Android Studio Dolphin 新版Logcat 使用指南:告别混乱日志,高效定位问题
android·android studio·logcat
Android-Flutter3 小时前
android Binder 应用层开发 详解
android·binder
文人sec16 小时前
MySQL主库出问题了,从库怎么办?备库为什么会延迟好几个小时?
android·数据库·mysql
hai_android16 小时前
不用 AIDL,手把手教你手写 Binder 代理类
android·kotlin
mmsx17 小时前
osmdroid 地图实战 03|地图的"分层世界":离线方案、图层模型与 Overlay 体系
android·前端
张文是假的啊18 小时前
IOC依赖注入问题:@Primary 和 @Qualifier的使用
android
换元不配限19 小时前
ConstraintLayout核心用法详解(三):引导线、屏障、组和占位
android·placeholder·barrier·约束布局·guideline
心平气和量大福大20 小时前
android studio(AS)工具-调试-统计总行数
android·ide·android studio
你的坚定1 天前
SurfaceFlinger合成一帧的完整流程
android