rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • App启动流程

  • 核心概念前置
  • Android 系统启动流程思维导图
  • App 冷启动完整流程(点击 Launcher 图标开始)
    • 阶段 1:Launcher 进程处理点击事件,向 AMS 发起启动请求
    • 阶段 2:SystemServer 进程(AMS)校验并准备启动 App
    • 阶段 3:SystemServer 进程(AMS)向 Zygote 进程请求孵化 App 进程
    • 阶段 4:App 进程初始化,向 AMS 注册并请求启动 Activity
    • 阶段 5:AMS 向 App 进程下发启动 Activity 指令
    • 阶段 6:App 进程启动 Activity,绘制界面
    • 全流程关键节点时序图
    • 关键步骤拆解(新手能懂的细节)
      • 1. 前置:指令如何从AMS到App进程?
      • 2. ApplicationThread → Handler 转发的核心原因
      • 3. performLaunchActivity() 的核心工作(源码简化逻辑)
      • 4. Application 生命周期(比你写的更完整)
      • 5. View渲染流程与Activity生命周期的联动
    • 易踩坑的关键细节(实战/面试高频)
    • 核心流程关键点
    • 实战优化核心
  • Binder线程池是什么?
    • 1. Binder的核心角色(跨进程通信基础)
    • 2. Binder线程池的本质
    • 3. 通俗例子
  • 为什么ApplicationThread要运行在Binder线程池(多线程)?
    • 问题1:单线程阻塞导致所有指令卡死
    • 问题2:不符合Android的通信设计规范
  • ApplicationThread的Binder线程池多线程的具体表现
    • 1. 源码级证据(ActivityThread核心逻辑)
    • 2. 直观现象(可通过日志验证)
    • 3. 多线程带来的问题与解决方案
    • 核心关键点总结
  • ApplicationThread 为什么不注册到 ServiceManager ?
    • 1. 先搞懂:ServiceManager的核心作用(为什么不是所有服务都要注册)
      • 两类Binder服务端的区别(关键)
      • 通俗类比
    • 2. ApplicationThread作为Binder服务端,如何和AMS建立通信?
      • 步骤1:AMS是“全局注册的Binder服务端”(先有基础)
      • 步骤2:App进程创建ApplicationThread(Binder服务端)
      • 步骤3:AMS保存ApplicationThread的Binder代理(关键)
      • 步骤4:AMS→App的指令流转(反向调用)
    • 3. 码级验证:attachApplication的核心逻辑
    • 4. 为什么ApplicationThread不需要注册到ServiceManager?
    • 5. 核心关键点总结
  • 核心 IPC 交互总结(进程间调用关系)
  • App 进程启动 Activity ,这个Activity是App进程创建的 还是AMS创建的?
    • 核心结论拆解
      • 1. AMS 的角色:“指挥者” 而非 “创建者”
      • 2. App 进程的角色:“执行者”+“创建者”
    • 关键代码佐证(Android 源码层面)
      • 1. AMS 侧:仅下发指令,不创建实例
      • 2. App 进程侧:主动创建 Activity 实例
    • 为什么 Activity 必须由 App 进程创建?
  • 影响启动速度的核心环节
  • 热启动与温启动流程(简化版)
  • 热启动流程
    • 热启动核心定义
    • 热启动完整流程(点击 Launcher 图标开始)
      • 阶段 1:Launcher 进程发起启动请求(同冷启动,但参数有差异)
      • 阶段 2:AMS 校验进程状态,直接下发启动指令
      • 阶段 3:App 进程恢复 / 重建 Activity,绘制界面
    • 热启动 vs 冷启动核心差异对比
    • 核心 IPC 交互总结(热启动仅 2 次 Binder 调用)
    • 热启动优化的核心切入点
  • 温启动流程
    • 温启动核心定义
    • 温启动完整流程(点击 Launcher 图标开始)
      • 阶段 1:Launcher 进程发起启动请求(同冷 / 热启动)
      • 阶段 2:AMS 校验状态,下发 “重建 Activity” 指令
      • 阶段 3:App 进程重建 Activity,绘制界面
    • 冷 / 温 / 热启动核心差异对比
    • 温启动优化的核心切入点
    • 关键补充:系统如何判定 “是否温启动”?
  • Activity 启动流程
  • 核心系统组件详解
    • 1. Zygote(孵化器进程)
      • 核心功能
      • 关键特点
    • 2. ServiceManager(系统服务管家)
      • 核心功能
      • 关键特点
    • 3. SystemServer(系统服务进程)
      • 核心功能
      • 启动的核心服务分类
    • 4. PowerManagerService(电源管理服务)
      • 核心功能
  • 核心组件的关系与执行先后顺序
    • 1. 组件之间的依赖关系
    • 2. 严格的执行先后顺序(系统启动阶段)
    • 3. 组件协作示例(App 启动时)
  • 总结
  • 资料

App启动流程

App启动速度优化
zygote

核心概念前置

在讲解流程前,先明确两个关键概念:

  1. 核心进程角色:

    • Launcher 进程:桌面应用进程,负责展示 App 图标、接收点击事件;
    • SystemServer 进程:系统核心进程(zygote 孵化),包含 ActivityManagerService(AMS)、PackageManagerService(PMS)等核心服务;
    • Zygote 进程:Android 系统的 “进程孵化器”,负责孵化新的 App 进程;
    • App 进程:冷启动时新建的目标 App 进程,承载 App 的所有业务逻辑。
  2. 核心 IPC 方式:

    Android 中进程间通信的核心是Binder(基于 C/S 架构的跨进程通信机制),以下流程中所有 IPC 均基于 Binder 实现。

Android 系统启动流程思维导图

App 冷启动完整流程(点击 Launcher 图标开始)

  1. Android App 冷启动的核心链路是:Launcher → AMS → Zygote → App进程 → AMS → App进程,其中除 AMS 向 Zygote 的调用用 Socket,其余均为 Binder IPC;
  2. Binder 是 Android 跨进程通信的核心,支撑了系统服务与应用进程、应用进程之间的交互;
  3. 冷启动的性能瓶颈主要在 Zygote 孵化进程、App 初始化、首屏绘制三个阶段,也是日常优化的重点。

阶段 1:Launcher 进程处理点击事件,向 AMS 发起启动请求

  1. 用户点击 App 图标:Launcher 的onClick()事件触发,封装启动参数(包名、启动 Activity 等);
  2. Launcher 进程 → SystemServer 进程(AMS):
    • IPC 调用:Launcher 通过ActivityManager.getService()获取 AMS 的 Binder 代理对象,调用AMS.startActivity()方法;
    • 核心数据:传递Intent(包含目标 App 包名、启动模式等)、用户 ID、启动标志(如 FLAG_ACTIVITY_NEW_TASK)。

阶段 2:SystemServer 进程(AMS)校验并准备启动 App

  1. AMS 权限 / 参数校验:
    • 调用 PMS(PackageManagerService)校验目标 App 是否安装、是否有启动权限;
    • 解析 App 的 AndroidManifest.xml,获取默认启动 Activity(<intent-filter>中 ACTION_MAIN+CATEGORY_LAUNCHER);
  2. AMS 判断进程状态:
    • 冷启动场景下,判定目标 App 无进程,触发 “新建进程 + 启动 Activity” 流程;
    • 记录 Activity 启动栈,维护任务栈(TaskStack)信息。

阶段 3:SystemServer 进程(AMS)向 Zygote 进程请求孵化 App 进程

  1. AMS → Zygote 进程:
    • IPC 调用:AMS 通过ZygoteProcess向 Zygote 进程发送孵化请求(基于 Socket 通信,Binder 不支持跨 UID 的 Zygote 进程调用);
    • 核心数据:传递 App 的 UID/GID、进程名、虚拟机参数(如堆大小)、启动类(ActivityThread)。
  2. Zygote 孵化 App 进程:
    • Zygote 通过fork()系统调用创建新进程(继承 Zygote 的虚拟机、类加载器等,避免重复初始化);
    • 新进程执行ActivityThread.main()方法,启动 App 的主线程 Looper,完成进程初始化。

阶段 4:App 进程初始化,向 AMS 注册并请求启动 Activity

  1. App 进程初始化:
    • 启动 ActivityThread(App 进程的核心主线程类),创建 ApplicationThread(Binder 线程,负责与 AMS 跨进程通信)和 H(Handler,负责线程切换,将 Binder 线程的消息转发到主线程)。;
    • 初始化主线程 Looper、Handler,创建Application对象,执行Application.attachBaseContext()、onCreate();
  2. App 进程 → SystemServer 进程(AMS):
    • IPC 调用:App 进程通过ApplicationThread向 AMS 发送attachApplication()请求,注册自身进程信息;
    • 核心数据:传递 App 进程的 PID、ApplicationThread 的 Binder 代理对象。

ApplicationThread是ActivityThread的内部类,作为ATMS回调应用进程的Binder接口:

final ApplicationThread mAppThread = new ApplicationThread();

// ActivityThread内部类
private class ApplicationThread extends IApplicationThread.Stub {
    public final void bindApplication(...) {
        sendMessage(H.BIND_APPLICATION, data);
    }
    
    public final void scheduleLaunchActivity(...) {
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }
}

应用进程使用H(Handler)处理消息:

class H extends Handler {
    public void handleMessage(Message msg) {
        case BIND_APPLICATION:
            handleBindApplication(data);
        case LAUNCH_ACTIVITY:
            handleLaunchActivity(r);
    }
}

阶段 5:AMS 向 App 进程下发启动 Activity 指令

  1. AMS 确认注册:AMS 收到 App 进程的注册请求后,确认进程已就绪;
  2. SystemServer 进程(AMS) → App 进程:
    • IPC 调用:AMS 通过 App 进程注册的ApplicationThread代理对象,调用scheduleLaunchActivity()方法;
    • 核心数据:传递启动 Activity 的组件信息、Intent、任务栈信息、窗口配置(如屏幕尺寸)。

阶段 6:App 进程启动 Activity,绘制界面

  1. App 进程处理启动指令:
    • ApplicationThread接收到指令后,通过主线程 Handler 将请求转发给 ActivityThread;
    • ActivityThread 执行performLaunchActivity():创建 Activity 对象、执行onCreate()/onStart()/onResume();
      1. 创建 Application 实例:调用 attachBaseContext() → 调用 onCreate()(开发者在此初始化全局资源)。
      2. 创建主 Activity 实例:执行 onCreate() → onStart() → onResume() 生命周期方法。
      3. 执行 View 渲染流程:measure → layout → draw,最终通过 SurfaceFlinger 合成显示到屏幕。

创建Application

handleBindApplication() 触发应用级初始化:

// frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
    // 1. 创建LoadedApk(代表加载的APK)
    final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
        appContext.getClassLoader(), false, true, false);
    
    // 2. 创建ContextImpl
    final ContextImpl appContext = ContextImpl.createAppContext(this, pi);
    
    // 3. 实例化Application
    Application app = pi.makeApplication(forceDefaultAppClass, instr);
    
    // 4. 安装ContentProviders
    if (!data.restrictedBackupMode) {
        installContentProviders(app, data.providers);
    }
    
    // 5. 回调Application.onCreate()
    mInstrumentation.callApplicationOnCreate(app);
}

关键步骤:

  1. 通过ClassLoader加载APK资源
  2. 创建应用级上下文
  3. 反射实例化自定义Application类
  4. 触发应用初始化回调

Application.attachBaseContext()何时调用?

在创建Application实例后立即调用:

// frameworks/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass, 
                                   Instrumentation instrumentation) {
    // 1. 创建Application实例
    Application app = mActivityThread.mInstrumentation.newApplication(
        cl, appClass, appContext);
    
    return app;
}

// frameworks/base/core/java/android/app/Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context) {
    Application app = getFactory(context).instantiateApplication(cl, className);
    // 关键调用
    app.attach(context);
    return app;
}

// frameworks/base/core/java/android/app/Application.java
final void attach(Context context) {
    attachBaseContext(context);  // 调用Application的protected方法
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

Activity实例化与生命周期

收到LAUNCH_ACTIVITY消息后,创建目标Activity:

// frameworks/base/core/java/android/app/ActivityThread.java
private Activity handleLaunchActivity(ActivityClientRecord r) {
    final Activity a = performLaunchActivity(r, null);
    return a;
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 1. 创建Activity实例
    Activity activity = mInstrumentation.newActivity(
        cl, component.getClassName(), r.intent);
    
    // 2. 创建Application(如果尚未创建)
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
    // 3. 关联Context
    Context appContext = createBaseContextForActivity(r, activity);
    activity.attach(appContext, ...);
    
    // 4. 回调onCreate()
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    
    return activity;
}
  1. 界面绘制与显示:
    • Activity 执行setContentView(),加载布局并通过 WindowManagerService(WMS)完成界面绘制;
    • WMS 将绘制好的 Surface 渲染到屏幕,用户看到 App 界面,冷启动完成。

全流程关键节点时序图

关键步骤拆解(新手能懂的细节)

1. 前置:指令如何从AMS到App进程?

  • AMS(ActivityManagerService)运行在system_server系统进程,App进程是独立的应用进程;
  • 两者通过Binder跨进程通信传递启动指令:AMS → Binder驱动 → App进程的ApplicationThread(ActivityThread的内部类,负责跨进程通信)。

2. ApplicationThread → Handler 转发的核心原因

  • ApplicationThread的回调方法运行在Binder线程池(非主线程);
  • Android规定:Activity/Application的生命周期方法必须在主线程执行;
  • 所以ApplicationThread会通过ActivityThread的主线程Handler(mH),将启动请求封装成Message,发送到主线程的MessageQueue;
  • 主线程Looper取出Message后,触发performLaunchActivity(),保证生命周期在主线程执行。

3. performLaunchActivity() 的核心工作(源码简化逻辑)

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 1. 创建Application实例(若未创建)
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
    // 2. 创建Activity实例(通过类加载器反射)
    Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    
    // 3. 关联Application上下文
    activity.attach(appContext, this, ...);
    
    // 4. 触发Activity生命周期
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    mInstrumentation.callActivityOnStart(activity);
    mInstrumentation.callActivityOnResume(activity);
    
    return activity;
}

✅ 关键:Application只在首次启动时创建,后续启动新Activity不会重复创建Application。

4. Application 生命周期(比你写的更完整)

attachBaseContext() → onCreate() → onConfigurationChanged()(配置变化)→ onLowMemory()(低内存)→ onTerminate()(仅模拟环境生效)
  • attachBaseContext():最早执行,此时Context已初始化,可做上下文相关初始化(如多语言、插件化);
  • onCreate():开发者主要的初始化入口(如路由、网络、缓存初始化)。

5. View渲染流程与Activity生命周期的联动

  • onCreate()中调用setContentView():只是加载布局文件到内存,未执行measure/layout/draw;
  • 真正的View渲染触发时机:onResume()执行后,ActivityThread通过WindowManager向WMS申请Surface,触发measure → layout → draw;
  • 渲染完成后,数据通过SurfaceFlinger(系统服务)合成最终帧,显示到屏幕。

易踩坑的关键细节(实战/面试高频)

  1. onResume() ≠ 界面可见:

    • onResume()只是Activity进入前台的生命周期标记,此时View可能还在渲染中,真正可见要等onWindowFocusChanged(true);
    • 若在onResume()中获取View宽高,会得到0(因为measure还没执行),需用View.post()或OnGlobalLayoutListener。
  2. Application.onCreate() 不能做耗时操作:

    • 它运行在主线程,耗时操作(如网络请求、复杂计算)会阻塞Activity启动,导致冷启动耗时过长。
  3. Handler转发的线程安全:

    • ApplicationThread的Binder线程池是多线程的,通过主线程Handler转发,保证了生命周期方法的线程安全。

核心流程关键点

  • 启动指令通过Binder跨进程从AMS到App进程,再通过Handler转发到主线程;
  • Application仅首次启动创建,生命周期:attachBaseContext() → onCreate();
  • Activity创建后依次执行onCreate() → onStart() → onResume(),随后触发View渲染;
  • 最终通过SurfaceFlinger完成屏幕显示。

实战优化核心

  • 减少Application.onCreate()的耗时操作(如懒加载);
  • 延迟非首屏必要的View渲染(如列表预加载);
  • 利用attachBaseContext()做早期上下文初始化。

简单记:Binder传指令,Handler调主线,App只创一次,渲染在Resume后。

Binder线程池是什么?

Binder机制 |

Binder线程池

1. Binder的核心角色(跨进程通信基础)

Android的跨进程通信(IPC)核心是Binder,任何两个进程通信都要遵循“客户端-服务端”模型:

  • 客户端:发起请求的一方(比如system_server进程的AMS,向App进程发启动Activity指令);
  • 服务端:处理请求的一方(比如App进程的ApplicationThread,接收AMS的指令);
  • Binder驱动:中间层,负责转发请求和响应,类似“快递员”。

2. Binder线程池的本质

  • 每个App进程启动时,系统会自动为其创建一个Binder线程池(属于App进程的子线程池);
  • 这个线程池的作用:专门处理“其他进程通过Binder发给当前App的请求”;
  • 线程池的特性:多线程、自动管理、可扩容——默认创建2-4个线程,若请求多,系统会自动增加线程数(上限一般16个)。

3. 通俗例子

把App进程比作“公司”,Binder线程池是“公司的客服部门”:

  • 客服部门有多个客服人员(多线程),而非只有1个;
  • 外部公司(比如system_server)打来的电话(Binder请求),会被随机分配给任意一个客服人员处理;
  • 即使一个客服在处理“启动Activity”的电话,另一个客服还能处理“暂停Activity”的电话,不会互相阻塞。

为什么ApplicationThread要运行在Binder线程池(多线程)?

ApplicationThread作为App进程和system_server进程(AMS)通信的“Binder服务端”,运行在App进程的Binder线程池中——这个线程池默认会创建多个线程(而非单线程)来处理AMS发来的跨进程请求,目的是避免单个请求阻塞导致整个通信链路卡死。

ApplicationThread是ActivityThread的内部类,且实现了IApplicationThread.Stub(Binder服务端接口),它的核心职责是接收AMS发来的所有跨进程指令(启动Activity、暂停Activity、销毁Activity、配置变化等)。

如果只用单线程处理这些指令,会出现致命问题:

问题1:单线程阻塞导致所有指令卡死

比如AMS发了两个指令:

  1. “启动Activity A”(耗时200ms);
  2. “暂停Activity B”(紧急,需立即处理)。

若单线程处理:必须等“启动A”完成后,才能处理“暂停B”,可能导致Activity B无法及时暂停,出现UI卡顿、ANR甚至系统异常。

问题2:不符合Android的通信设计规范

Android框架设计时,明确要求“Binder服务端的回调方法必须运行在非主线程”——因为:

  • 主线程要处理UI渲染、事件分发,若Binder请求(比如AMS的启动指令)跑在主线程,一旦请求耗时,会直接阻塞主线程,导致App卡死;
  • 多线程的Binder线程池,把跨进程请求的处理和主线程解耦,保证主线程的流畅性。

ApplicationThread的Binder线程池多线程的具体表现

1. 源码级证据(ActivityThread核心逻辑)

ActivityThread的attach()方法中,会将ApplicationThread注册到AMS,同时系统会自动把ApplicationThread的回调方法分配到Binder线程池的不同线程:

// ActivityThread.java
private void attach(boolean system, long startSeq) {
    // 1. 创建ApplicationThread(Binder服务端)
    mAppThread = new ApplicationThread();
    // 2. 获取AMS的Binder代理(客户端)
    final IActivityManager mgr = ActivityManager.getService();
    try {
        // 3. 将ApplicationThread注册到AMS,后续AMS通过Binder调用AppThread的方法
        mgr.attachApplication(mAppThread, startSeq);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

// ApplicationThread的回调方法(运行在Binder线程池)
class ApplicationThread extends IApplicationThread.Stub {
    // 处理AMS发来的“启动Activity”指令
    @Override
    public final void scheduleLaunchActivity(...) {
        // 此方法运行在Binder线程池的某一个线程(非主线程)
        // 所以需要通过主线程Handler转发到主线程执行
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

    // 处理AMS发来的“暂停Activity”指令
    @Override
    public final void schedulePauseActivity(...) {
        // 此方法可能运行在Binder线程池的另一个线程
        sendMessage(H.PAUSE_ACTIVITY, r);
    }
}

2. 直观现象(可通过日志验证)

在ApplicationThread的回调方法中打印线程名,会发现不同指令的线程名不同:

// 自定义ApplicationThread的回调(仅演示)
@Override
public void scheduleLaunchActivity(...) {
    Log.d("Binder线程", "启动Activity的线程:" + Thread.currentThread().getName());
    // 输出:Binder线程: 启动Activity的线程:Binder:1234_2
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

@Override
public void schedulePauseActivity(...) {
    Log.d("Binder线程", "暂停Activity的线程:" + Thread.currentThread().getName());
    // 输出:Binder线程: 暂停Activity的线程:Binder:1234_3
}

✅ 关键:Binder:1234_2、Binder:1234_3 代表App进程(PID=1234)的Binder线程池中的第2、3个线程,证明是多线程处理。

3. 多线程带来的问题与解决方案

Binder线程池是多线程的,意味着ApplicationThread的多个回调方法可能并发执行,这会带来线程安全问题:

  • 比如:AMS同时发“启动Activity A”和“销毁Activity A”的指令,可能导致并发修改Activity状态;
  • 解决方案:ApplicationThread收到指令后,统一通过主线程的Handler(mH)转发到主线程执行——主线程是单线程的,天然避免并发问题,这也是为什么你之前看到“通过Handler转发给ActivityThread”的核心原因。

核心关键点总结

  1. Binder线程池的本质:App进程的子线程池,专门处理其他进程(如AMS)发来的Binder请求,默认多线程(2-4个,可扩容);
  2. ApplicationThread的角色:作为Binder服务端,运行在这个多线程池里,接收AMS的所有跨进程指令;
  3. 多线程的目的:避免单个请求阻塞导致所有指令卡死,保证跨进程通信的高效性;
  4. 多线程的副作用:并发执行带来线程安全问题,因此需要通过主线程Handler转发指令,回到单线程处理。

简单记:Binder线程池是App的“多线程客服部”,处理外部进程的请求;ApplicationThread是客服人员,收到请求后统一交给“主线程总经理”处理,既高效又安全。

ApplicationThread 为什么不注册到 ServiceManager ?

ApplicationThread确实是Binder服务端,但它不需要注册到ServiceManager,而是通过“私有Binder通信”的方式和AMS建立绑定。

  1. ApplicationThread 是App进程的Binder服务端(负责接收AMS的指令);
  2. 并非所有Binder服务端都要注册到ServiceManager——只有“系统级全局服务”(如AMS、WMS、PMS)才需要注册到ServiceManager;
  3. ApplicationThread是AMS的“私有Binder服务端”:只和AMS建立一对一的Binder连接,无需全局注册,这是Android进程通信的“按需绑定”设计。

1. 先搞懂:ServiceManager的核心作用(为什么不是所有服务都要注册)

ServiceManager是Android系统的“Binder服务注册表”,核心职责是:

  • 管理系统级、全局可访问的Binder服务(如AMS、WMS、PMS);
  • 提供“服务名→Binder对象”的查询能力,让任意进程能通过服务名找到对应的Binder服务端。

两类Binder服务端的区别(关键)

服务端类型是否注册到ServiceManager适用场景例子
系统级全局服务是所有进程都需要访问的服务AMS、WMS、PMS
进程间私有Binder服务否两个进程之间的一对一通信ApplicationThread、自定义IPC

通俗类比

把ServiceManager比作“全国企业黄页”:

  • AMS、WMS这类系统服务是“全国连锁企业”,需要登黄页,让所有进程(企业)都能找到;
  • ApplicationThread是“AMS的专属供应商”:只和AMS打交道,不需要登黄页,只要AMS知道它的联系方式就行。

2. ApplicationThread作为Binder服务端,如何和AMS建立通信?

你疑惑的“为什么不注册到ServiceManager”,核心是ApplicationThread和AMS的通信是“反向绑定”,而非“全局注册”,完整流程如下:

步骤1:AMS是“全局注册的Binder服务端”(先有基础)

  • AMS(ActivityManagerService)运行在system_server进程,启动时会把自己注册到ServiceManager,服务名是"activity";
  • 任意App进程都能通过ServiceManager.getService("activity")获取AMS的Binder代理(客户端)——这是App能主动调用AMS的基础。

步骤2:App进程创建ApplicationThread(Binder服务端)

ActivityThread的attach()方法中,会创建ApplicationThread实例(实现了IApplicationThread.Stub,即Binder服务端):

// ActivityThread.java
private void attach(boolean system, long startSeq) {
    // 1. 创建Binder服务端:ApplicationThread
    mAppThread = new ApplicationThread();
    // 2. 获取AMS的Binder客户端代理(从ServiceManager拿到)
    final IActivityManager ams = ActivityManager.getService(); // 本质是ServiceManager.getService("activity")
    
    try {
        // 3. 核心操作:把ApplicationThread的Binder对象传给AMS
        ams.attachApplication(mAppThread, startSeq);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

步骤3:AMS保存ApplicationThread的Binder代理(关键)

当App进程调用ams.attachApplication(mAppThread)时:

  • mAppThread是App进程的Binder服务端对象,跨进程传递时会被Binder驱动自动转换成AMS进程中的Binder代理对象;
  • AMS收到这个代理对象后,会把它和当前App进程的信息(PID、包名等)绑定,保存到自己的内存中(比如mProcessNames、mActiveApplications等容器);
  • 此后AMS要给App发指令(如启动Activity),直接通过这个保存的代理对象调用ApplicationThread的方法即可。

步骤4:AMS→App的指令流转(反向调用)

graph TD
    A[AMS system_server进程] -->|持有ApplicationThread的Binder代理| B[Binder驱动]
    B -->|转发到App进程| C[ApplicationThread Binder服务端]
    C -->|运行在Binder线程池| D[通过Handler转发到主线程]
    D -->|执行生命周期| E[ActivityThread]

3. 码级验证:attachApplication的核心逻辑

我们看AMS的attachApplication()方法(简化版),就能明白它如何保存ApplicationThread的代理:

// ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread app, long startSeq) {
    // 1. app是ApplicationThread的Binder代理对象(来自App进程)
    if (app == null) {
        throw new IllegalArgumentException("app is null");
    }
    
    // 2. 获取App进程的信息(PID、包名等)
    final int pid = Binder.getCallingPid();
    final String processName = getProcessNameByPid(pid);
    
    // 3. 把ApplicationThread代理和进程信息绑定,保存到AMS内存中
    ProcessRecord appProcess = getProcessRecordLocked(pid, processName);
    appProcess.appThread = app; // 关键:保存代理对象
    
    // 4. 后续AMS给App发指令时,直接用appProcess.appThread调用
    // 比如启动Activity:appProcess.appThread.scheduleLaunchActivity(...)
}

✅ 关键:AMS通过attachApplication()拿到了ApplicationThread的Binder代理,相当于“保存了App进程的通信地址”,后续无需ServiceManager,直接一对一通信。

4. 为什么ApplicationThread不需要注册到ServiceManager?

  1. 无全局访问需求:ApplicationThread只需要和AMS通信,其他进程(如电话、相机)根本不需要访问它,注册到ServiceManager完全没必要;
  2. 降低系统开销:ServiceManager是全局单点服务,注册的服务越多,查询和维护成本越高;私有Binder通信按需绑定,更高效;
  3. 安全可控:只让AMS持有ApplicationThread的代理,避免其他恶意进程通过ServiceManager获取App的Binder服务端,提升安全性;
  4. 生命周期匹配:ApplicationThread的生命周期和App进程一致,App退出后代理自动失效,无需ServiceManager做额外清理。

5. 核心关键点总结

  1. ApplicationThread 是App进程的Binder服务端,但它是AMS的“私有服务端”,而非全局服务;
  2. 只有系统级全局服务(AMS、WMS)需要注册到ServiceManager,私有Binder服务只需“按需绑定”;
  3. ActivityThread.attach()的核心是:把ApplicationThread的Binder对象传给AMS,让AMS保存其代理,从而建立“AMS→App”的反向通信链路;
  4. 整个过程的本质是:App通过ServiceManager找到AMS,再把自己的Binder服务端代理交给AMS,实现双向通信。

简单记:

  • ServiceManager管“全局服务”(AMS、WMS);
  • 私有Binder管“一对一通信”(AMS↔ApplicationThread);
  • ApplicationThread不登“黄页”,只给AMS留“私人联系方式”。

核心 IPC 交互总结(进程间调用关系)

调用方向IPC 方式核心目的关键接口 / 对象
Launcher 进程 → SystemServer(AMS)Binder(C/S)请求启动目标 AppAMS.startActivity()
SystemServer(AMS) → Zygote 进程Socket请求孵化新的 App 进程ZygoteProcess.forkAndSpecialize()
App 进程 → SystemServer(AMS)Binder(C/S)注册 App 进程,告知 AMS 已就绪ApplicationThread.attachApplication()
SystemServer(AMS) → App 进程Binder(C/S)下发启动 Activity 的指令ApplicationThread.scheduleLaunchActivity()
  1. Binder 的核心作用:

    Binder 是 Android 中最核心的 IPC 机制,相比 Socket / 管道 / 共享内存,具有

    性能高、权限管控细、支持跨进程对象传递

    的优势,上述流程中除了 AMS 向 Zygote 的调用(Zygote 是 root 权限,Binder 不支持跨 UID 调用),其余进程间通信均基于 Binder。

  2. 冷启动与热启动的核心区别:

    热启动时,App 进程已存在,无需 Zygote 孵化进程的步骤,直接执行 “AMS 向 App 进程下发启动 Activity 指令” 阶段,启动速度远快于冷启动。

  3. 启动优化的核心切入点:

    • 减少 Application.onCreate () 中的耗时操作(如初始化 SDK);
    • 延迟加载非核心组件,优先渲染界面;
    • 优化布局层级,减少首屏绘制时间。

App 进程启动 Activity ,这个Activity是App进程创建的 还是AMS创建的?

Activity 是由 App 进程自己创建的,AMS 仅负责下发 “启动指令”,不参与 Activity 的实例化过程。

  1. Activity 实例的创建者:App 进程(ActivityThread)通过类加载器 + 构造方法创建,全程在 App 进程内完成;
  2. AMS 的核心作用:仅负责 “指令下发” 和 “状态管控”,不参与任何实例化逻辑;
  3. 核心边界:进程隔离决定了 SystemServer 进程(AMS)无法跨进程创建 App 进程内的对象,这是 Android 系统架构的底层设计原则。

核心结论拆解

1. AMS 的角色:“指挥者” 而非 “创建者”

AMS(SystemServer 进程中)的核心作用是:

  • 校验启动权限、维护任务栈、判断进程状态;
  • 向 App 进程下发 “启动指定 Activity” 的指令(通过 Binder IPC 调用ApplicationThread.scheduleLaunchActivity());
  • 传递启动所需的元数据(如 Intent、Activity 组件信息、窗口配置);
  • 但绝不会直接创建 Activity 实例—— 因为 Activity 是 App 的业务组件,必须运行在 App 进程的虚拟机中,AMS 所在的 SystemServer 进程无法访问 App 的类加载器、资源文件,也无权创建 App 内的对象。

2. App 进程的角色:“执行者”+“创建者”

App 进程收到 AMS 的启动指令后,完整掌控 Activity 的创建流程:

  1. ApplicationThread(App 进程内的 Binder 对象)接收到 AMS 的指令后,通过主线程 Handler 将请求转发给 ActivityThread;
  2. ActivityThread 调用performLaunchActivity()方法,核心逻辑包括:
    • 通过ClassLoader加载目标 Activity 的类(App 进程自己的类加载器,加载 Apk 中的 Activity.class);
    • 调用 Activity 的构造方法(new Activity()),创建实例;
    • 执行attach()方法,绑定 Context、Window 等核心资源;
    • 依次调用onCreate()/onStart()/onResume()等生命周期方法。

关键代码佐证(Android 源码层面)

1. AMS 侧:仅下发指令,不创建实例

// SystemServer进程 - AMS源码片段
private final boolean startProcessLocked(...) {
    // 向Zygote请求孵化App进程,仅传递启动参数
    zygoteProcess.startProcess(...);
    // 向已就绪的App进程下发启动Activity指令
    app.thread.scheduleLaunchActivity(...); // 仅传递元数据,无创建逻辑
}

2. App 进程侧:主动创建 Activity 实例

// App进程 - ActivityThread源码片段
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    Activity activity = null;
    try {
        // 1. 加载Activity类(App进程的类加载器)
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 2. 创建Activity实例(核心!App进程内执行new操作)
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        // 3. 初始化Activity(绑定Context、执行生命周期)
        activity.attach(...);
        mInstrumentation.callActivityOnCreate(activity, r.state);
    } catch (Exception e) {
        // 异常处理
    }
    return activity;
}

为什么 Activity 必须由 App 进程创建?

  1. 进程隔离:Android 的进程是独立的沙箱,SystemServer 进程(AMS)无法访问 App 进程的内存空间、类加载器、资源文件;
  2. 类加载限制:Activity 是 App 的自定义类,只有 App 进程的PathClassLoader能加载 Apk 中的 Activity.class,AMS 所在的 SystemServer 进程使用的是系统类加载器(BootClassLoader/SystemClassLoader),无法加载 App 的业务类;
  3. 生命周期管控:Activity 的生命周期(如onCreate())需要访问 App 的 Application、资源、组件,这些都仅存在于 App 进程中,AMS 无法模拟。

影响启动速度的核心环节

  1. Zygote 预加载:系统预加载框架类和资源,减少 App 进程初始化时间,开发者无法干预。
  2. Application.onCreate():主线程耗时操作(如 SDK 初始化)是启动延迟的主要原因,需异步 / 延迟处理。
  3. Activity.onCreate():setContentView() 加载复杂布局(如嵌套层级多、大图片)会增加绘制耗时,需简化布局。
  4. 首次绘制(First Draw):只有完成首次绘制,用户才能看到界面,之前的 “黑白屏” 是系统的临时过渡窗口(见「App 黑白屏问题」)。

热启动与温启动流程(简化版)

冷启动是 “全流程”,热启动和温启动因进程已存在,流程更短:

启动类型核心特点流程简化耗时对比
热启动进程、Application、Activity 均存在点击图标 → AMS 唤起 Activity → onResume()最快(< 500ms)
温启动进程、Application 存在,Activity 需重建点击图标 → 重建 Activity(onCreate() → onResume())中等(500ms~1s)
冷启动进程、Application、Activity 均需创建全流程(6 个阶段)最慢(1~3s)

热启动流程

热启动核心定义

热启动是指:App 进程已存在(如退到后台但未被系统杀死),用户从 Launcher / 最近任务列表点击图标重新打开 App 的场景。

核心特征:无需新建进程、无需重新初始化 Application,仅需恢复 / 重启目标 Activity,启动速度通常比冷启动快 10 倍以上。

热启动完整流程(点击 Launcher 图标开始)

阶段 1:Launcher 进程发起启动请求(同冷启动,但参数有差异)

  1. 用户点击 App 图标,Launcher 的onClick()触发,封装启动 Intent(包含FLAG_ACTIVITY_NEW_TASK等标志);

  2. Launcher 进程 → SystemServer 进程(AMS)

    (Binder IPC):

    • 调用AMS.startActivity(),传递启动参数;
    • 核心差异:Intent 中会携带 “目标 App 进程已存在” 的隐含信息,AMS 无需触发进程孵化流程。

阶段 2:AMS 校验进程状态,直接下发启动指令

  1. AMS 校验:

    • 检查目标 App 的进程状态(通过 PID / 包名判定进程已存活);
    • 校验 Activity 任务栈:若目标 Activity 已在栈中(如退后台未销毁),则标记 “恢复 Activity”;若已销毁,则标记 “重新创建 Activity”;
    • 无需调用 PMS 重新解析 Manifest(冷启动需解析,热启动直接复用缓存的组件信息);
  2. SystemServer 进程(AMS) → App 进程

    (Binder IPC):

    • 调用 App 进程中ApplicationThread.scheduleLaunchActivity()(恢复 Activity)或scheduleResumeActivity()(重启 Activity);
    • 核心数据:仅传递 Activity 栈信息、窗口配置,无需传递进程初始化参数。

阶段 3:App 进程恢复 / 重建 Activity,绘制界面

  1. App 进程接收指令(无进程初始化步骤):

    • ApplicationThread通过主线程 Handler 将指令转发给 ActivityThread;
    • 核心差异:无需执行Application.attachBaseContext()/onCreate()(Application 已初始化),无需创建新的 Looper / 主线程;
  2. Activity 处理逻辑(分两种场景):

    场景核心操作
    Activity 未销毁(退后台)ActivityThread 调用performResumeActivity(),执行onRestart()→onStart()→onResume(),直接恢复界面;
    Activity 已销毁(栈内重建)ActivityThread 调用performLaunchActivity()创建新 Activity 实例(仅创建 Activity,不初始化 Application),执行onCreate()→onStart()→onResume();
  3. 界面绘制:

    • 复用已加载的布局资源、缓存的图片 / 数据,快速完成 Surface 渲染;
    • 无冷启动的 “应用初始化→资源加载” 耗时步骤,首屏秒出。

热启动 vs 冷启动核心差异对比

流程节点冷启动热启动
进程状态无进程,需 Zygote 孵化进程已存在,直接复用
AMS 核心操作孵化进程 + 下发启动指令直接下发恢复 / 重启指令
IPC 交互4 次(Launcher→AMS→Zygote→App→AMS→App)2 次(Launcher→AMS→App)
App 初始化执行 Application 生命周期不执行 Application 生命周期
Activity 创建全新创建(类加载 + 构造方法)恢复(复用实例)或重建(仅 Activity)
资源加载重新加载所有资源复用已缓存的资源
启动耗时数百 ms~ 数秒数十 ms

核心 IPC 交互总结(热启动仅 2 次 Binder 调用)

调用方向IPC 方式核心目的
Launcher 进程 → SystemServer(AMS)Binder请求启动 App(告知进程已存在)
SystemServer(AMS) → App 进程Binder下发恢复 / 重启 Activity 的指令

热启动优化的核心切入点

  1. 避免 Activity 频繁销毁:合理设置launchMode(如singleTop/singleTask),减少栈内重建;
  2. 缓存核心资源:首屏图片、网络数据缓存到内存,热启动时直接复用;
  3. 优化onRestart()/onResume():避免在这些生命周期中执行耗时操作(如网络请求、大量数据解析);
  4. 减少后台进程被杀死:通过合理的保活策略(如前台服务、WorkManager)降低进程被杀概率,维持热启动状态。

温启动流程

  1. 温启动的核心是 “进程存活 + Activity 重建”,跳过了冷启动的 “进程孵化 + Application 初始化”,但需执行 Activity 的全新创建流程;
  2. IPC 交互仅 2 次 Binder 调用(同热启动),但 Activity 创建逻辑同冷启动(无 Application 初始化);
  3. 温启动优化的关键是 “复用进程内缓存 + 减少 Activity 重建后的耗时操作”,核心目标是向热启动的速度靠拢。

温启动核心定义

温启动(Warm Start):App 进程仍存活,但目标 Activity 已被销毁(如用户返回退出 Activity、系统回收 Activity 实例),用户再次点击图标启动 App 的场景。

核心特征:

  • ✅ App 进程已存在(无需 Zygote 孵化);
  • ❌ 目标 Activity 实例已销毁(需重新创建);
  • ❌ Application 无需重新初始化(进程存活,Application 实例仍在);
  • 启动速度:介于冷启动(慢)和热启动(快)之间,通常比冷启动快 50% 以上。

温启动完整流程(点击 Launcher 图标开始)

阶段 1:Launcher 进程发起启动请求(同冷 / 热启动)

  1. 用户点击 App 图标,Launcher 触发onClick(),封装启动 Intent(含包名、默认启动 Activity);

  2. Launcher 进程 → SystemServer 进程(AMS)

    (Binder IPC):

    • 调用AMS.startActivity(),传递启动参数;
    • 核心差异:AMS 校验后判定 “进程存活,但目标 Activity 无实例”,触发 “重建 Activity” 流程。

阶段 2:AMS 校验状态,下发 “重建 Activity” 指令

  1. AMS 核心校验:

    • 检查 App 进程状态:PID 有效、进程未被杀死(复用已有进程);
    • 检查 Activity 任务栈:目标 Activity(默认启动页)已从栈中销毁(如用户执行finish()、系统因内存不足回收);
    • 复用缓存的 Manifest 信息(无需重新解析 Apk),仅重新确认默认启动 Activity;
  2. SystemServer 进程(AMS) → App 进程

    (Binder IPC):

    • 调用 App 进程中ApplicationThread.scheduleLaunchActivity()(注意:是scheduleLaunchActivity而非热启动的scheduleResumeActivity);
    • 核心数据:传递 Activity 组件信息、Intent、任务栈配置,无进程初始化参数。

阶段 3:App 进程重建 Activity,绘制界面

  1. App 进程接收指令(无进程 / Application 初始化步骤):

    • ApplicationThread通过主线程 Handler 将指令转发给 ActivityThread;
    • 核心差异:
      • 无需执行Application.attachBaseContext()/onCreate()(Application 实例已存在);
      • 无需初始化主线程 Looper、类加载器等(进程存活,这些资源已就绪);
  2. Activity 重建流程:

    ActivityThread 调用performLaunchActivity()(同冷启动的 Activity 创建逻辑,但无 Application 初始化):

    • 步骤 1:通过 App 进程的类加载器加载 Activity 类(复用已有类加载器);
    • 步骤 2:创建 Activity 实例(new Activity());
    • 步骤 3:执行 Activity 生命周期:onCreate() → onStart() → onResume();
  3. 界面绘制:

    • 复用进程内已缓存的资源(如图片、布局文件、网络数据缓存);
    • 通过 WindowManagerService(WMS)渲染界面,完成启动。

冷 / 温 / 热启动核心差异对比

维度冷启动温启动热启动
进程状态无进程,需 Zygote 孵化进程存活进程存活
Application 状态需重新创建 + 执行 onCreate ()已存在,不执行 onCreate ()已存在,不执行 onCreate ()
Activity 状态全新创建重建(实例已销毁)恢复(实例未销毁)
核心 IPC 次数4 次(Launcher→AMS→Zygote→App→AMS→App)2 次(Launcher→AMS→App)2 次(Launcher→AMS→App)
关键调用方法AMS.startProcess ()(孵化进程)AMS.scheduleLaunchActivity()AMS.scheduleResumeActivity()
启动耗时最长(数百 ms~ 数秒)中等(数十 ms~ 百 ms)最短(数 ms~ 数十 ms)
典型场景首次启动、进程被系统杀死后启动进程存活但 Activity 已销毁退后台未杀进程,直接恢复

温启动优化的核心切入点

  1. 缓存 Activity 关键数据:在onSaveInstanceState()中保存 Activity 的核心数据(如表单内容、列表滚动位置),温启动时在onCreate()中恢复,避免重复请求网络 / 解析数据;
  2. 复用进程内缓存资源:将图片、网络数据、配置信息缓存到 Application 或内存缓存中,重建 Activity 时直接复用,减少onCreate()耗时;
  3. 避免非必要的 Activity 销毁:合理设计返回逻辑,避免用户误操作导致核心 Activity 被finish();
  4. 优化onCreate()逻辑:将非首屏必要的初始化操作(如 SDK 初始化、埋点)延迟到onResume()或异步执行,缩短温启动首屏时间。

关键补充:系统如何判定 “是否温启动”?

Android 系统通过两个维度判定:

  1. 进程存活判定:AMS 维护 “进程列表”,通过 PID 和进程状态(PROCESS_STATE_TOP/PROCESS_STATE_CACHED)判断进程是否存活;
  2. Activity 实例判定:AMS 维护 “任务栈(TaskStack)” 和 “ActivityRecord”,每个 ActivityRecord 对应一个 Activity 实例,若 ActivityRecord 已被移除(finish()/ 系统回收),则判定需重建。

Activity 启动流程

Activity 启动是 App 启动的核心子流程,跨进程通信是核心特点,分为 6 步(以启动新 Activity 为例):

  1. 应用层发起请求:当前 Activity 调用 startActivity(Intent) → 最终调用 Instrumentation.execStartActivity()。

  2. Binder 跨进程调用 AMS:Instrumentation 通过 Binder 向 SystemServer 进程的 AMS 发送启动请求。

  3. AMS 权限与栈管理:

    • AMS 检查权限、验证 Intent 合法性;
    • 根据 launchMode 决定创建新实例或复用已有实例;
    • 向 Zygote 请求创建进程(若进程未启动)。
  4. AMS 通知 App 进程创建 Activity:

    • AMS 通过 Binder 向 App 进程的 ApplicationThread 发送创建 Activity 的指令。
  5. 线程切换与 Activity 实例化:

    • ApplicationThread 接收到指令后,通过 H(Handler) 将任务转发到主线程(ActivityThread);
    • ActivityThread 通过 ClassLoader 创建 Activity 实例;
    • 依次调用 onCreate() → onStart() → onResume()。
  6. AMS 同步状态:Activity 生命周期执行完成后,ApplicationThread 向 AMS 报告状态,AMS 更新任务栈信息。

核心系统组件详解

1. Zygote(孵化器进程)

核心功能

  • 进程孵化器:是 Android 系统中所有 App 进程和 SystemServer 进程的父进程,由 init 进程启动(解析 init.rc 配置文件)。
  • 预加载资源:启动时会预加载 Android 核心类库、系统资源(如主题、字符串)、初始化 Dalvik/ART 虚拟机,避免每个 App 进程重复初始化,提升进程创建速度。
  • 进程创建:通过 fork() 系统调用创建子进程(App 进程或 SystemServer 进程),采用写时复制机制,减少内存开销。

关键特点

  • 自身是一个特殊的 Dalvik/ART 进程,不执行具体业务逻辑,仅负责孵化进程。
  • 通过 socket 与 SystemServer 通信,接收创建进程的请求。

2. ServiceManager(系统服务管家)

核心功能

  • 系统服务注册中心:是 Android 系统的「Binder 大管家」,负责管理所有系统服务的注册与查询。
  • 服务注册:所有系统服务(如 AMS、WMS、PMS)启动后,都会向 ServiceManager 注册(通过 addService() 方法)。
  • 服务查询:客户端(如 App 进程)需要使用系统服务时,通过 getService() 向 ServiceManager 查询,获取服务的 Binder 代理对象。

关键特点

  • 由 init 进程启动,是第一个启动的系统服务,运行在 SystemServer 进程启动前。
  • 自身不提供业务服务,仅负责「服务的注册与转发」。

3. SystemServer(系统服务进程)

核心功能

  • 系统服务的宿主进程:是 Android 系统的「核心服务容器」,几乎所有核心系统服务都运行在该进程中(如 AMS、WMS、PMS、PowerManagerService 等)。
  • 启动与管理系统服务:由 Zygote 进程 fork() 生成,启动后会依次启动各类系统服务,并将服务注册到 ServiceManager。
  • 系统核心调度:协调各系统服务之间的通信,是 App 进程与系统服务交互的「中转站」。

启动的核心服务分类

服务类型代表服务核心作用
生命周期管理AMS(ActivityManagerService)管理 Activity 生命周期、进程调度
窗口管理WMS(WindowManagerService)管理窗口的显示、层级、大小
包管理PMS(PackageManagerService)管理 App 安装、卸载、权限
电源管理PowerManagerService管理设备电源状态、休眠 / 唤醒

4. PowerManagerService(电源管理服务)

核心功能

  • 设备电源状态管理:是 Android 系统中负责电源策略、休眠唤醒、亮度调节的核心服务,运行在 SystemServer 进程。

  • 核心职责:

    1. 监听电源键、电池状态、传感器事件(如距离传感器);
    2. 管理设备状态(开机、休眠、唤醒、关机);
    3. 调节屏幕亮度、控制背光开关;
    4. 实现电源节能策略(如屏幕自动熄灭、进程休眠)。
  • 对外接口:通过 PowerManager 类向应用层提供 API(如唤醒屏幕、设置屏幕亮度)。

核心组件的关系与执行先后顺序

1. 组件之间的依赖关系

init 进程 → ServiceManager → Zygote → SystemServer → 各类系统服务(含 PowerManagerService)→ App 进程
  • init 是根进程:Android 系统启动后,内核首先启动 init 进程,它是所有进程的祖先。
  • ServiceManager 是服务管家:由 init 启动,为后续系统服务提供注册 / 查询能力。
  • Zygote 是孵化器:由 init 启动,负责孵化 SystemServer 和所有 App 进程。
  • SystemServer 是服务容器:由 Zygote 孵化,启动并管理 PowerManagerService 等所有系统服务,且将服务注册到 ServiceManager。
  • PowerManagerService 是子服务:运行在 SystemServer 进程内部,依赖 SystemServer 提供的运行环境,同时通过 ServiceManager 对外提供服务。

2. 严格的执行先后顺序(系统启动阶段)

系统启动时,组件的启动顺序是固定且不可逆的,具体步骤如下:

  1. 内核启动:Android 设备开机后,首先加载内核,初始化硬件驱动。

  2. 启动 init 进程:内核启动后,启动 init 进程,init 解析 init.rc 配置文件。

  3. 启动 ServiceManager:init 进程根据配置启动 ServiceManager,使其进入等待状态,准备接收服务注册请求。

  4. 启动 Zygote 进程:init 进程启动 Zygote 进程,Zygote 预加载核心类库和资源,初始化虚拟机,监听 socket 端口。

  5. Zygote 孵化 SystemServer 进程:

    • Zygote 通过 fork() 创建 SystemServer 进程;
    • SystemServer 进程启动后,初始化主线程,依次启动各类系统服务(包括 PowerManagerService、AMS、WMS 等)。
  6. 系统服务注册到 ServiceManager:每个系统服务启动后,都会调用 ServiceManager.addService() 完成注册。

  7. PowerManagerService 启动:作为 SystemServer 启动的服务之一,启动后注册到 ServiceManager,开始管理设备电源状态。

  8. 启动 Launcher 进程:SystemServer 启动完成后,AMS 会启动 Launcher 进程(桌面应用),用户可点击图标启动 App。

  9. Zygote 孵化 App 进程:用户启动 App 时,AMS 通过 socket 通知 Zygote,Zygote fork() 生成 App 进程。

3. 组件协作示例(App 启动时)

当用户启动 App 时,核心组件的协作流程:

用户点击 Launcher → Launcher 通过 ServiceManager 获取 AMS 代理 → AMS 通过 socket 通知 Zygote → Zygote fork App 进程 → App 进程通过 ServiceManager 获取 PowerManagerService 代理(若需电源相关操作)

总结

  1. App 启动流程:用户触发 → AMS 请求 → Zygote 孵化进程 → ActivityThread 初始化 → Application 与 Activity 启动 → 界面显示。
  2. Activity 启动流程:应用层请求 → Binder 调用 AMS → AMS 管理栈与进程 → App 进程线程切换 → Activity 实例化与生命周期执行。
  3. 核心组件关系:init 是根进程,ServiceManager 是服务管家,Zygote 是进程孵化器,SystemServer 是服务容器,PowerManagerService 是 SystemServer 内的子服务。
  4. 执行先后:init → ServiceManager → Zygote → SystemServer → PowerManagerService → App 进程。

资料

从源码解析Android应用启动全流程:从点击图标到Activity渲染的深度剖析

最近更新:: 2026/3/24 22:00
Contributors: luokaiwen