当前位置: 首页 > news >正文

Android 应用进程启动

跨进程协作过程:

详细步骤解析

第一步:发起 Fork 请求(从 System Server 到 Zygote)
  1. 起点: 当系统需要启动一个应用组件(如 Activity)而该应用进程不存在时,ActivityManagerService (AMS) 会决定要启动一个新进程
  2. 准备参数: AMS 会收集所有启动新进程所需的信息,例如:
    ○ 应用包名: 用于识别应用身份
    ○ 进程名: 通常是包名或带有特定后缀(如 :background
    ○ UID/GID: 应用的用户和组 ID,用于沙盒隔离
    ○ 目标 SDK 版本: 用于兼容性控制
    ○ 入口类名: 即 android.app.ActivityThread
    ○ 其他标志位: 用于控制运行行为(如是否为调试应用)
  3. 跨进程通信: AMS(运行在 system_server 进程)通过 Unix Domain Socket 向 Zygote 进程发送一个 fork 新进程的请求。这是通过 ZygoteProcess 类(其内部是 ZygoteState)建立 Socket 连接并发送参数实现的
第二步:Zygote Fork 新进程
  1. 接收请求: Zygote 进程通过 ZygoteServer 一直在其 Socket 上监听来自 AMS 的请求
  2. 解析参数: Zygote 收到请求后,会解析参数,准备好 fork 操作
  3. Fork 系统调用: Zygote 调用 fork() 系统调用。这是最关键的一步
    ○ Zygote 的优化: 得益于 Copy-on-Write (COW) 机制,Zygote 在启动时已预加载了大量的 Android 框架类和资源(如 ActivityThreadContextImpl, 通用资源等)。新 fork 出的进程几乎零成本地继承了所有这些预加载的类和信息,这极大地加快了应用启动速度并节省了内存
  4. 子进程(新应用进程)初始化:
    ○ 处理 Socket: 子进程会关闭从 Zygote 继承下来的、用于监听 fork 请求的 Socket,因为它不需要这个
    ○ 清理状态: 清理从 Zygote 继承的、不需要的线程和内存状态
  5. 执行入口方法: 在子进程中,会调用 ZygoteInit.zygoteInit() 方法,该方法主要做三件事:
    ○ 启动 Binder 线程池: 调用 ZygoteInit.nativeZygoteInit() -> AppRuntime.onZygoteInit() -> ProcessState.startThreadPool()。这启动了 Binder 机制,使得新进程具备了 IPC 能力,可以与其他系统服务(如 AMS)进行通信
    ○ 关闭 Log 流: 关闭从 Zygote 继承的日志流
    ○ 进入主入口: 最终,通过反射调用 AMS 请求中指定的入口类的 main() 方法,即 android.app.ActivityThread.main(String[] args)
第三步:ActivityThread 接管和应用初始化
  1. ActivityThread.main(): 这是应用进程的“主函数”和入口点
    ○ 主线程初始化: 它运行在应用的主线程(UI 线程)上
    ○ 创建 ActivityThread 实例: ActivityThread 对象被创建,它是应用进程中的核心管理器,负责调度和管理四大组件
    ○ 创建 Looper: 调用 Looper.prepareMainLooper() 和 Looper.loop(),为主线程建立消息队列(MessageQueue),开始处理消息(如 UI 事件、生命周期回调等)
  2. attach 到系统服务: ActivityThread.main() 方法会调用 thread.attach(false)(其中 thread 是 ActivityThread 实例)
    ○ 这个方法会通过 Binder 调用 IActivityManager.attachApplication(),最终通知到 AMS,告诉它:“我这个新进程已经启动完毕,并且准备好了”
  3. AMS 完成后续启动: AMS 收到 attachApplication() 回调后,会知道新进程已就绪。然后它会:
    ○ 通过 Binder IPC 回调到应用进程的 ApplicationThread(一个实现了 IApplicationThread 接口的 Binder 对象,是 ActivityThread 的内部类)
    ○ 发送 BIND_APPLICATION 等消息到应用进程的消息队列
  4. 加载应用 APK 和创建 Application:
    ○ 主线程的 H(Handler)会处理 BIND_APPLICATION 消息
    ○ 这会触发 ActivityThread.handleBindApplication() 方法
    ○ 在该方法中,会:
    ◎ 创建 ContextImpl(Context 的真正实现)
    ◎ 使用 LoadedApk 类的信息,通过 ClassLoader 加载应用的 APK
    ◎ 实例化应用的 Application 对象(根据 AndroidManifest.xml 中 <application> 的 android:name 属性,默认为 android.app.Application
    ◎ 调用 Application.onCreate() 生命周期方法。这是应用开发者可以接受到的第一个自定义回调

总结与关键点

  • Zygote 的作用: 预加载通用框架资源和类,通过 fork 快速创建新进程,节省内存和启动时间
  • 进程分工:
    ○ system_server (AMS): 决策者。决定何时、为何启动新进程,并收集启动参数
    ○ Zygote 孵化器。负责执行 fork(),创建进程实例
    ○ 应用进程: 执行者。运行 ActivityThread 和应用代码
  • 两次 IPC:
    ① 
    AMS -> Zygote (via Socket):请求 fork
    ② 应用进程 -> AMS (via Binder):通知 attach,完成后续启动流程
  • 主线程消息循环: ActivityThread.main() 的核心是启动 Looper,使得主线程成为一个事件驱动的工作模式,所有来自系统的回调(如生命周期、界面绘制)都通过消息队列来调度

文章转载自:

http://jz8U4viS.qgxnw.cn
http://iMceBGtn.qgxnw.cn
http://lASNUEZT.qgxnw.cn
http://MP2Lgfac.qgxnw.cn
http://wKotUg2d.qgxnw.cn
http://GVZW9tQG.qgxnw.cn
http://O6usuCVp.qgxnw.cn
http://kt4YiU0C.qgxnw.cn
http://in1YbC0E.qgxnw.cn
http://rMZAeLY4.qgxnw.cn
http://o9yRctch.qgxnw.cn
http://W4xMdt4X.qgxnw.cn
http://cf5VE3x8.qgxnw.cn
http://Ax18DEA5.qgxnw.cn
http://nPWzTV6c.qgxnw.cn
http://XctbvNFY.qgxnw.cn
http://h1BhNugo.qgxnw.cn
http://0XH792eZ.qgxnw.cn
http://RaEtODcm.qgxnw.cn
http://qdwdLjBo.qgxnw.cn
http://xD6LUkjw.qgxnw.cn
http://MPnkhHms.qgxnw.cn
http://eEjS4jvG.qgxnw.cn
http://iDCJi98p.qgxnw.cn
http://RQaMhuYm.qgxnw.cn
http://CGDnLDLe.qgxnw.cn
http://41ZRpKsy.qgxnw.cn
http://Ef2H2cgN.qgxnw.cn
http://otnsg1l1.qgxnw.cn
http://xXlR9vEb.qgxnw.cn
http://www.dtcms.com/a/368849.html

相关文章:

  • WebSocket:实现实时通信的革命性技术
  • 【Rust 入门】01. 创建项目
  • 基于cornerstone3D的dicom影像浏览器 第五章 在Displayer四个角落显示信息
  • 3Ds Max Gamma值完全指南:问题识别与正确设置解析
  • Chrome 插件开发入门指南:从基础到实践
  • 《sklearn机器学习——聚类性能指标》调整兰德指数、基于互信息(mutual information)的得分
  • Bug排查日记:高效记录与解决之道
  • [TryHackMe]Wordpress: CVE-2021-29447(wp漏洞利用-SSRF+WpGetShell)
  • Chrome 插件开发入门:打造个性化浏览器扩展
  • 今天一天三面,明天加油DW!!!
  • Java基础篇02:基本语法
  • 当前的大部分的AI,可能已经分到了传统那桌了!Causal AI:颠覆传统机器学习的下一代人工智能技术,让AI真正理解“为什么“!
  • Firefox Window 开发流程(二)
  • 树莓派传感器扩展板资料
  • setup函数相关【3】
  • 基于单片机坐姿提醒系统/久坐提醒设计
  • 请求超过Spring线程池的最大线程(处理逻辑)
  • 使用buildroot交叉编译swupdate 记录
  • PyTorch 中的循环神经网络 (RNN/LSTM):时序数据处理实战指南
  • Preprocessing Model in MPC 7 - Matrix Triples and Convolutions Lookup Tables
  • 职场突围:我的转岗反思录
  • Nature Electronics 用于解码疲劳水平的眼睑软体磁弹性传感器
  • 【AI产品思路】AI 原型设计工具横评:产品经理视角下的 v0、Bolt 与 Lovable
  • 如何使用宝塔API批量操作Windows目录文件:从获取文件列表到删除文件的完整示例
  • 极大似然估计与概率图模型:统计建模的黄金组合
  • K8S删除命名空间卡住一直Terminating状态
  • 【清爽加速】Windows 11 Pro 24H2-Emmy精简系统
  • Overleaf教程+Latex教程
  • 获取DLL动态库的版本信息(dumpbin.exe)
  • AI时代企业获取精准流量与实现增长的GEO新引擎