news 2026/7/5 3:20:07

Android随笔-APP首次启动流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android随笔-APP首次启动流程

从用户点击应用图标到 Activity 执行 onCreate() 的完整流程,涉及Launcher 进程 → SystemServer 进程 → Zygote 进程 → 应用进程之间的多轮跨进程通信。以下是详细拆解:

一、核心通信方式概览

通信双方IPC 方式作用
Launcher → AMS/ATMSBinder IPC发送启动 Activity 的请求
AMS → ZygoteSocket请求 fork 创建新应用进程
AMS → 应用进程Binder IPC通过 ApplicationThread 代理回调应用进程
应用进程 → AMSBinder IPC应用进程向 AMS 注册自身

:Android 10+ 中 AMS 的 Activity 管理职责已拆分至 ActivityTaskManagerService (ATMS),但核心逻辑不变。以下以 AMS 代指系统侧服务 。

二、详细流程

阶段 1:Launcher 发起启动请求(Binder IPC)

用户点击桌面图标时,Launcher 进程(本质也是一个普通应用)执行以下调用链:

// Launcher 点击图标Launcher.onClick()startActivity(intent)Instrumentation.execStartActivity()ActivityManager.getService().startActivity()// 跨进程 Binder 调用
  • ActivityManager.getService() 返回的是 AMS 的 Binder 代理对象(IActivityManager 接口的代理)
  • 通过 Binder 驱动 将请求发送到 SystemServer 进程中的 AMS
  • 传递的 Intent 包含目标组件信息:component = com.example.app/.MainActivity

阶段 2:AMS 处理启动请求(SystemServer 进程)

AMS收到请求后,执行以下关键步骤:

  1. 权限校验— 检查调用方是否有启动权限
  2. 创建 ActivityRecord— 在 AMS 内部为本次启动创建对应的 ActivityRecord 对象,记录 Activity 状态
  3. 检查进程状态— 通过 ProcessRecord 查询目标应用进程是否存在
    • 若进程已存在 → 直接走 realStartActivityLocked() 启动 Activity
    • 若进程不存在 → 进入进程创建流程

阶段 3:AMS 请求 Zygote 创建新进程(Socket)

当 AMS 发现目标进程不存在时:

AMS.startProcessLocked()Process.start()ZygoteProcess.startViaZygote()→ 通过Socket连接Zygote进程,发送 fork 参数
  • 为什么用 Socket 而非 Binder?
    • Zygote 进程在启动时初始化并预加载了大量类和资源,需要保持"干净"状态
    • 如果使用 Binder,Zygote 需注册到 ServiceManager,会引入额外依赖
    • Socket 通信更简单、开销更小,且 fork 后子进程无需继承 Binder 线程池的复杂状态
  • Zygote 收到请求后,调用 fork() 创建子进程,子进程继承了预加载的环境,然后反射调用 ActivityThread.main() 作为应用进程入口

阶段 4:应用进程初始化(ActivityThread.main)

新创建的应用进程执行 ActivityThread.main():

publicstaticvoidmain(String[]args){// 1. 初始化主线程 LooperLooper.prepareMainLooper();// 2. 创建 ActivityThread 实例ActivityThreadthread=newActivityThread();thread.attach(false);// 关键:向 AMS 注册// 3. 创建 ApplicationThread(Binder 服务端)// 4. 进入消息循环,等待 AMS 指令Looper.loop();}
  • ActivityThread 是应用进程的主线程管理类,每个应用进程只有一个实例
  • ApplicationThread 是 ActivityThread 的内部类,继承 IApplicationThread.Stub,作为应用进程向 AMS 暴露的 Binder 服务端接口
  • thread.attach(false) 通过 Binder 调用 AMS 的 attachApplication() 方法,将ApplicationThread 的 Binder 代理注册到 AMS 下

阶段 5:AMS 回调应用进程创建 Application(Binder IPC)

AMS 收到 attachApplication() 后,通过 ApplicationThread 的代理回调应用进程:

AMS.attachApplicationLocked()ApplicationThreadProxy.bindApplication()// Binder 跨进程调用→ 应用进程ApplicationThread.bindApplication()sendMessage(H.BIND_APPLICATION,data)// 向主线程 Handler 发消息ActivityThread.handleBindApplication()

handleBindApplication() 的核心逻辑:

privatevoidhandleBindApplication(AppBindDatadata){// 1. 创建 LoadedApk(代表已加载的 APK)// 2. 创建 ContextImpl(应用级 Context)// 3. 反射创建 Instrumentation// 4. 创建 Application 实例Applicationapp=data.info.makeApplication(false,mInstrumentation);// 5. 调用 Application.attachBaseContext() — 最早的应用入口app.attach(context);// 内部调用 attachBaseContext()// 6. 安装 ContentProviders(比 onCreate 更早)installContentProviders(app,data.providers);// 7. 调用 Application.onCreate()mInstrumentation.callApplicationOnCreate(app);}

关键顺序:

attachBaseContext() → ContentProvider.onCreate() → Application.onCreate()

阶段 6:AMS 请求启动 Activity(Binder IPC)

Application 初始化完成后,AMS 再次通过 ApplicationThread 代理发送启动 Activity 的请求:

AMS.realStartActivityLocked()ClientTransaction.schedule()ApplicationThreadProxy.scheduleLaunchActivity()// Binder 跨进程→ 应用进程ApplicationThread.scheduleLaunchActivity()sendMessage(H.LAUNCH_ACTIVITY,r)// 向主线程发消息ActivityThread.handleLaunchActivity()

阶段 7:应用进程创建 Activity 并执行 onCreate()

handleLaunchActivity() 调用 performLaunchActivity() 完成 Activity 创建:

privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){// 1. 创建 Activity 的 ContextContextImplappContext=createBaseContextForActivity(r);// 2. 反射创建 Activity 实例Activityactivity=mInstrumentation.newActivity(cl,component.getClassName(),r.intent);// 3. 获取 Application 实例Applicationapp=r.packageInfo.makeApplication(false,mInstrumentation);// 4. 调用 Activity.attach() — 创建 PhoneWindow、绑定 WindowManageractivity.attach(appContext,this,getInstrumentation(),r.token,r.ident,app,r.intent,r.activityInfo,title,r.parent,...);// 5. 调用 Activity.onCreate()if(r.isPersistable()){mInstrumentation.callActivityOnCreate(activity,r.state,r.persistentState);}else{mInstrumentation.callActivityOnCreate(activity,r.state);}// 6. 设置 Activity 状态为 ON_CREATEr.setState(ON_CREATE);}

Activity.attach() 内部关键操作:

  • 调用 attachBaseContext(context) — 绑定 Context
  • 创建 PhoneWindow — 这是 Activity 的窗口实现
  • 创建 WindowManager — 与系统窗口管理服务绑定
  • 初始化 FragmentController 等内部组件

Instrumentation.callActivityOnCreate() 最终调用:

publicvoidcallActivityOnCreate(Activityactivity,Bundleicicle){activity.performCreate(icicle);// 内部调用 activity.onCreate(icicle)}

三、关键类与角色总结

类/组件所属进程角色
LauncherLauncher 进程桌面应用,接收点击事件,发起启动请求
ActivityManagerService (AMS)SystemServer管理系统所有 Activity 的生命周期和进程
ActivityTaskManagerService (ATMS)SystemServerAndroid 10+ 负责 Activity 栈管理(从 AMS 拆分)
ZygoteZygote 进程所有应用进程的父进程,通过 fork 快速创建新进程
ActivityThread应用进程应用主线程管理类,入口为main()
ApplicationThread应用进程应用进程暴露给 AMS 的 Binder 服务端
IApplicationThread接口定义AMS 调用应用进程的 Binder 接口
Instrumentation应用进程应用进程的"管家",封装 Activity/Application 的创建和生命周期调用
ActivityRecordAMS 内部AMS 中代表一个 Activity 实例的管理对象
ProcessRecordAMS 内部AMS 中记录进程状态信息的对象

四、总结

点击图标后,Launcher 通过 Binder 请求 AMS → AMS 通过 Socket 让 Zygote fork 进程 →新进程通过 Binder 向 AMS 注册 → AMS 通过 Binder 回调应用进程创建 Application → 再回调创建Activity 并执行 onCreate()。整个过程经历了 2 次 Binder 往返 + 1 次 Socket 通信 + 多次 Handler 消息调度。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 3:19:27

uniCloud JQLSchema知识点总结

一、文件结构与核心文件作用 1. 目录位置 项目 uniCloud/支付宝云-xxx/database/ 下两类核心文件: xxx.schema.json:数据表结构定义文件(集合 Schema) 定义数据表字段、类型、必填、默认值、权限、数据校验规则必须右键上传部署…

作者头像 李华
网站建设 2026/7/5 3:14:50

DMDUL:达梦数据库离线抽取数据工具

项目简介 DMDUL 是一个面向达梦数据库的数据文件离线分析与数据抽取工具。 项目目标是在数据库无法正常打开、实例无法正常启动、系统表空间或用户表空间需要离线分析时,通过读取达梦数据库相关文件,辅助完成对象识别、表结构分析、数据页扫描和数据导…

作者头像 李华
网站建设 2026/7/5 3:12:41

3D点云处理核心任务实践指南:从配准、分割到检测的工程化路径

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 最近在整理一个三维重建项目的历史代码,发现里面有一段处理点云配准的脚本,用的是十年前那套经典的ICP算法。跑…

作者头像 李华
网站建设 2026/7/5 3:11:55

游戏音频解密的艺术:如何将加密的ACB文件转换为WAV格式

游戏音频解密的艺术:如何将加密的ACB文件转换为WAV格式 【免费下载链接】acbDecrypter 项目地址: https://gitcode.com/gh_mirrors/ac/acbDecrypter 你是否曾想从喜欢的游戏中提取背景音乐,却发现音频文件被加密成ACB格式无法播放?面…

作者头像 李华