Android App 启动原理

Android App 启动原理

Android 中说的 App 启动原理,本质上是在回答一个问题:

当我们点击桌面图标后,一个应用是如何从"还没运行"到"页面显示出来"的?

这个过程会涉及:

  • Launcher(桌面应用)
  • AMS(ActivityManagerService
  • Zygote
  • 应用进程创建
  • ActivityThread
  • Application
  • 启动目标 Activity

如果从整体上看,可以先记住这一条主线:

点击桌面图标 -> Launcher 发起启动请求 -> AMS 校验和调度 -> Zygote fork 新进程 -> 应用进程启动 -> 创建 Application -> 启动 Activity -> 页面显示


1. 先理解什么叫"App 启动"

通常我们说 App 启动,分成两类:

  • 冷启动:应用进程不存在,需要新建进程
  • 热启动:应用进程已经存在,只是把界面重新切回前台
  • 温启动 :进程还在,但需要重新创建 Activity

面试里最常问、也最重要的是:冷启动流程

因为冷启动把 Android 框架里最核心的一整套机制都串起来了。


2. 点击图标后,第一步发生了什么

用户点击桌面图标时,真正响应点击事件的是 Launcher,也就是桌面程序。

Launcher 本身也是一个普通 Android 应用,只不过它承担了桌面和应用入口的职责。

点击图标后,Launcher 会拿到目标应用的 Intent 信息,然后调用启动流程,本质上会发起一次 startActivity() 请求。

这时候事情还没有直接交给目标 App,而是先进入系统服务。

也就是说:

  • Launcher 不负责真正创建目标应用进程
  • 真正的启动调度者是系统服务
  • 这个核心服务就是 AMS

3. AMS 在启动流程中的作用

AMS 全称是 ActivityManagerService,它是 Android 中负责组件调度和进程管理的核心系统服务之一。

当 Launcher 发起启动请求后,AMS 会做几件关键事情:

  1. 校验目标 Activity 是否存在、是否可启动
  2. 检查目标应用进程是否已经存在
  3. 如果进程不存在,就创建应用进程
  4. 进程创建完成后,再通知应用去启动目标 Activity

所以 AMS 的角色可以理解成:

它不直接画页面,但它负责把"该由谁启动、何时启动、在哪个进程启动"安排清楚。


4. 如果进程不存在,就需要创建进程

这一步是冷启动的核心。

Android 不会让每个应用随意自己创建进程,而是通过 Zygote 来统一孵化应用进程。

4.1 什么是 Zygote

Zygote 是 Android 系统中非常关键的一个进程,可以理解成"应用进程的模板进程"。

它会提前完成很多通用初始化工作,比如:

  • 启动虚拟机
  • 加载系统类
  • 预加载常用资源

这样做的好处是:

  • 后续创建应用进程更快
  • 通过 fork 机制复用父进程资源,减少内存开销

4.2 AMS 如何让 Zygote 创建进程

当 AMS 发现目标 App 进程还没启动时,会向 Zygote 发送创建进程请求。

然后 Zygote 通过 fork() 创建出一个新的应用进程。

这个新进程创建出来后,就拥有了独立的:

  • 进程空间
  • 虚拟机环境
  • 主线程

到这里,应用已经不再只是"一个安装包",而是变成了"一个真正运行中的 Linux 进程"。


5. 新进程启动后,谁来接管应用主线程

新进程被创建后,并不是马上就显示页面,而是会先进入应用自己的运行入口。

这个入口对应的核心类是:

ActivityThread

很多人容易误解,名字里带了 Thread,就以为它只是一个线程类。实际上它更像是:

应用进程主线程的管理者。

它负责在应用进程里完成很多关键工作,比如:

  • 创建主线程消息循环
  • 和 AMS 进行通信
  • 创建 Application
  • 创建并启动 Activity

可以简单理解为:

AMS 负责"系统侧调度",ActivityThread 负责"应用侧落地执行"。


6. Application 是什么时候创建的

在启动目标 Activity 之前,系统会先创建应用级别的对象,也就是 Application

典型流程是:

  1. 创建 LoadedApk 等运行环境信息
  2. 创建应用的 Context
  3. 通过反射创建 Application 实例
  4. 回调 Application#onCreate()

这也是为什么我们经常会在 Application#onCreate() 中做一些全局初始化,比如:

  • 日志框架初始化
  • 路由初始化
  • 网络库初始化
  • 崩溃监控初始化

但是要注意:

这里的代码越重,冷启动就越慢。

因为 Application 还没走完,首页通常也还没真正显示出来。


7. Activity 是如何被启动出来的

当应用进程准备好之后,AMS 会通知应用进程去启动目标 Activity

应用进程中的 ActivityThread 收到消息后,会执行对应的启动流程,大致包括:

  1. 创建 Activity 实例
  2. 创建 Context
  3. 关联 PhoneWindow
  4. 调用 Activity#attach()
  5. 依次回调生命周期方法

常见启动顺序通常是:

  • onCreate()
  • onStart()
  • onResume()

onCreate() 中,一般会执行:

  • setContentView()
  • 初始化 View
  • 初始化数据
  • 注册监听器

当界面完成测量、布局、绘制后,用户才真正看到页面。


8. 从源码视角看启动链路

如果从高层源码链路去记,可以抓住下面这条主干:

  1. Launcher 发起 startActivity()
  2. 请求进入系统进程中的 AMS
  3. AMS 判断目标进程是否存在
  4. 不存在则请求 Zygote fork 新进程
  5. 新进程启动后进入 ActivityThread.main()
  6. 创建 Application
  7. ActivityThread 收到启动 Activity 的消息
  8. 创建并回调目标 Activity
  9. 完成页面绘制,启动结束

这条链路不要求每一步都背源码细节,但至少要知道:

  • 谁发起请求
  • 谁负责调度
  • 谁负责创建进程
  • 谁负责在应用侧执行生命周期

9. 为什么冷启动会慢

冷启动慢,本质上是因为它要做的事情太多,而且很多事情都集中在主线程早期阶段。

常见耗时点包括:

  • 进程创建本身有成本
  • Application#onCreate() 做了太多初始化
  • 首页 Activity#onCreate() 逻辑太重
  • 首屏布局层级太深,绘制耗时高
  • 同步 I/O、数据库、网络阻塞主线程
  • SDK 初始化过多

可以理解成:

冷启动慢,不一定慢在"启动框架流程",更常见的是慢在业务初始化代码。


10. 启动优化一般优化什么

做启动优化时,核心目标是:

让首屏更早可见,让主线程更少阻塞。

常见优化方向有:

  • 延迟初始化非核心组件
  • 按优先级拆分初始化任务
  • 异步执行耗时任务
  • 减少首页布局复杂度
  • 避免主线程 I/O
  • 使用启动器或任务编排框架统一管理初始化顺序

例如:

  • 统计、埋点、更新检查可以延后
  • 不影响首屏的 SDK 可以放到子线程
  • 首屏只加载最必要的数据

11. 面试中可以怎么概括

如果面试官让你简单介绍 App 启动原理,可以这样回答:

Android App 启动本质上是从 Launcher 点击图标开始,Launcher 通过系统服务发起启动请求,AMS 负责统一调度;如果目标进程不存在,AMS 会通知 Zygote fork 出新的应用进程。新进程启动后会进入 ActivityThread,先创建 Application,再创建并启动目标 Activity,最终完成页面绘制,用户看到首页。

如果面试官继续追问,可以继续往下展开:

  • 冷启动、热启动、温启动的区别
  • Zygote 为什么能加快启动
  • ApplicationActivity 的创建顺序
  • 启动优化一般优化哪些点

12. 一张简化流程图

可以把整个过程记成下面这张图:

Launcher -> AMS -> Zygote -> App Process -> ActivityThread -> Application -> Activity -> View 显示


13. 一句话总结

App 启动原理的核心,就是系统先决定"要不要创建进程",再由应用进程完成 ApplicationActivity 的创建,最后把页面绘制出来。

如果只记 3 个关键词,可以记:

  • AMS:负责调度
  • Zygote:负责创建进程
  • ActivityThread:负责在应用进程中执行启动流程

推荐面试题点我传送 链接:

https://www.toutiao.com/article/7629148616564818484/?log_from=2a3e05473a27c_1776384210421

相关推荐
TechMix3 小时前
【性能工具】atrace、systrace、perfetto抓取的trace文件有何不同?
android·性能优化
张小潇3 小时前
AOSP15 WMS/AMS系统开发 - 窗口层级源码分析
android·前端
努力努力再努力wz5 小时前
【MySQL入门系列】掌握表数据的 CRUD:DML 核心语法与执行逻辑解析
android·开发语言·数据结构·数据库·c++·b树·mysql
zh_xuan7 小时前
Android gradle任务
android·gradle构建
Grackers8 小时前
Android Perfetto 系列 10:Binder 调度与锁竞争
android·binder
李白你好8 小时前
Android 自动化渗透测试指令生成
android·自动化
CeshirenTester9 小时前
Claude Code 不只是会写代码:这 10 个 Skills,才是效率分水岭
android·开发语言·kotlin
朝星11 小时前
Android开发[2]:Flow
android·kotlin
zzb158011 小时前
Android Activity 与 Intent 学习笔记
android·笔记·学习