Android Activity启动流程详解

devtools/2025/3/3 15:06:08/

目录

Activity 启动流程详细解析

1. 应用层发起启动请求

1.1 调用 startActivity()

1.2 通过 Instrumentation 转发请求

AMS%20%E9%98%B6%E6%AE%B5%EF%BC%89-toc" name="tableOfContents" style="margin-left:80px">2. 系统服务处理(AMS 阶段)

Binder%20IPC%20%E9%80%9A%E4%BF%A1-toc" name="tableOfContents" style="margin-left:120px">2.1 Binder IPC 通信

AMS%20%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B-toc" name="tableOfContents" style="margin-left:120px">2.2 AMS 处理流程

2.3 跨进程回调 ApplicationThread

3. 目标进程初始化(ActivityThread 阶段)

3.1 进程创建(Zygote Fork)

3.2 初始化 ActivityThread

3.3 创建 Application 对象

4. 目标 Activity 的创建与生命周期

AMS%20%E7%9A%84%E5%90%AF%E5%8A%A8%E8%AF%B7%E6%B1%82-toc" name="tableOfContents" style="margin-left:120px">4.1 处理 AMS 的启动请求

4.2 创建 Activity 实例

4.3 生命周期回调

5. 界面渲染(WindowManager 与 View 系统)

5.1 视图树构建

5.2 视图测量、布局、绘制

5.3 同步到屏幕

6. 流程图解

7. 关键机制深度解析

Binder%20IPC%20%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8-toc" name="tableOfContents" style="margin-left:120px">7.1 Binder IPC 在启动流程中的作用

7.2 启动模式(LaunchMode)的影响

7.3 性能优化点

8. 总结


Activity 启动流程详细解析

Activity 的启动流程是 Android 系统中涉及多个组件协作的核心机制,从用户调用 startActivity() 到目标 Activity 完成界面渲染,整个过程分为 应用层请求、系统服务处理、进程管理、界面渲染 四个阶段,涉及 Binder IPC、AMS、Zygote、ActivityThread、WindowManager 等关键组件。以下是分步骤详细解析:


1. 应用层发起启动请求

1.1 调用 startActivity()
  • 入口:通过 Activity.startActivity(Intent) 或 Context.startActivity(Intent) 发起请求。

  • Intent 参数

    java">Intent intent = new Intent(this, TargetActivity.class);
    startActivity(intent);
  • 关键操作

    • Intent 封装目标 Activity 的类名、包名、启动模式(launchMode)等信息。

    • 调用 Instrumentation.execStartActivity()(实际执行启动逻辑)。

1.2 通过 Instrumentation 转发请求
  • 跨进程通信入口

    java">// Activity.java
    Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
  • 作用Instrumentation 是系统监控应用与组件交互的“钩子”,负责将启动请求通过 Binder 传递给 AMS


AMS%20%E9%98%B6%E6%AE%B5%EF%BC%89" name="2.%20%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%A4%84%E7%90%86%EF%BC%88AMS%20%E9%98%B6%E6%AE%B5%EF%BC%89">2. 系统服务处理(AMS 阶段)

Binder%20IPC%20%E9%80%9A%E4%BF%A1" name="2.1%20Binder%20IPC%20%E9%80%9A%E4%BF%A1">2.1 Binder IPC 通信
  • 客户端:应用进程通过 ActivityManagerProxyAMSBinder 代理对象)发送请求。

  • 服务端:请求到达 ActivityManagerServiceAMS),执行 startActivity() 核心逻辑。

AMS%20%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B" name="2.2%20AMS%20%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B">2.2 AMS 处理流程
  • 步骤

    1. 权限验证:检查调用方是否有权限启动目标 Activity。

    2. 解析 Intent

      • 根据 Intent 中的 ComponentName 解析目标 Activity 信息。

      • 若未显式指定类名,通过 PackageManagerService 匹配隐式 Intent。

    3. 任务栈(Task Stack)管理

      • 根据目标 Activity 的 launchMode(如 standardsingleTop)决定是否复用现有实例或创建新任务栈。

      • 例如:singleTask 会清除目标 Activity 上方的其他 Activity。

    4. 进程检查

      • 若目标 Activity 所属应用进程未启动,触发 Zygote 创建新进程。

      • 若进程已存在,直接复用。

2.3 跨进程回调 ApplicationThread
  • Binder 回调AMS 通过 IApplicationThread 接口(ActivityThread 的内部类)通知应用进程处理后续逻辑。

  • 关键代码

    java">// AMS 通过 Binder 调用应用进程的 ApplicationThread.scheduleLaunchActivity()
    app.thread.scheduleLaunchActivity(intent, ...);

3. 目标进程初始化(ActivityThread 阶段)

3.1 进程创建(Zygote Fork)
  • 触发条件:若目标应用进程未启动,AMS 通过 Zygote 进程 fork 新进程。

  • 流程

    1. AMS 向 Zygote 发送 socket 请求。

    2. Zygote 复制自身进程,生成新进程。

    3. 新进程执行 ActivityThread.main() 入口方法。

3.2 初始化 ActivityThread
  • 主线程初始化

    java">// ActivityThread.java
    public static void main(String[] args) {Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false); // 绑定到 AMSLooper.loop();
    }
  • 绑定 AMSActivityThread.attach() 通过 BinderAMS 注册应用进程。

3.3 创建 Application 对象
  • 触发AMS 回调 bindApplication()

  • 流程

    1. 加载 Application 类(通过 ClassLoader)。

    2. 实例化 Application 并调用 onCreate()

    3. 初始化 ContentProvider(按优先级顺序)。


4. 目标 Activity 的创建与生命周期

AMS%20%E7%9A%84%E5%90%AF%E5%8A%A8%E8%AF%B7%E6%B1%82" name="4.1%20%E5%A4%84%E7%90%86%20AMS%20%E7%9A%84%E5%90%AF%E5%8A%A8%E8%AF%B7%E6%B1%82">4.1 处理 AMS 的启动请求
  • 回调入口ApplicationThread.scheduleLaunchActivity()

  • 封装参数:将 AMS 传递的数据封装为 ActivityClientRecord

  • 发送消息:通过 Handler 将启动请求发送到主线程消息队列。

4.2 创建 Activity 实例
  • 反射创建实例

    java">// ActivityThread.java
    java.lang.ClassLoader cl = appContext.getClassLoader();
    Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), intent);
  • 关键对象

    • ContextImpl:Activity 的上下文环境,持有 ResourcesPackageInfo 等。

    • Window:每个 Activity 关联一个 PhoneWindow 对象。

4.3 生命周期回调
  • 顺序调用

    1. onCreate():初始化界面(setContentView())。

    2. onStart():Activity 可见但未聚焦。

    3. onResume():Activity 进入前台并获取焦点。

  • 触发界面渲染onResume() 完成后,WindowManager 将 DecorView 添加到屏幕。


5. 界面渲染(WindowManager 与 View 系统)

5.1 视图树构建
  • setContentView()

    java">// Activity.java
    public void setContentView(@LayoutRes int layoutResID) {getWindow().setContentView(layoutResID);initWindowDecorActionBar();
    }
    • PhoneWindow 创建 DecorView 并加载布局文件。

5.2 视图测量、布局、绘制
  • ViewRootImpl:管理视图树的三大流程:

    1. measure():计算 View 的尺寸。

    2. layout():确定 View 的位置。

    3. draw():将 View 绘制到屏幕上。

5.3 同步到屏幕

  • WindowManager.addView()

    java">// WindowManagerGlobal.java
    ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
    root.setView(view, wparams, panelParentView);
    • ViewRootImpl 通过 Choreographer 监听垂直同步信号(VSync),触发界面刷新。


6. 流程图解

用户调用 startActivity()
        │
        ↓
Instrumentation.execStartActivity()
        │
        ↓ (Binder IPC)
AMS.startActivity()
        │
        ↓
AMS 解析 Intent、检查权限、管理任务栈
        │
        ↓
目标进程是否存在? ── 否 → Zygote fork 新进程
        │
        ↓
AMS 通过 ApplicationThread 回调目标进程
        │
        ↓ (Handler 消息机制)
ActivityThread.handleLaunchActivity()
        │
        ↓
创建 Activity 实例 → onCreate() → onStart() → onResume()
        │
        ↓
WindowManager 添加 DecorView
        │
        ↓
ViewRootImpl 触发 measure/layout/draw
        │
        ↓
界面显示到屏幕


7. 关键机制深度解析

Binder%20IPC%20%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8" name="7.1%20Binder%20IPC%20%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8">7.1 Binder IPC 在启动流程中的作用
  • 客户端:应用进程通过 ActivityManagerProxy 发送请求。

  • 服务端AMS 运行在 system_server 进程,通过 Binder 线程池处理请求。

  • 跨进程回调AMS 通过 IApplicationThread 接口回调应用进程。

7.2 启动模式(LaunchMode)的影响
  • standard:默认模式,每次启动新实例。

  • singleTop:栈顶复用,触发 onNewIntent()

  • singleTask:栈内复用,清除上方 Activity。

  • singleInstance:独占任务栈,全局唯一实例。

7.3 性能优化点
  • 冷启动优化:减少 Application.onCreate() 和首屏 Activity 的初始化耗时。

  • 延迟加载:将非关键操作移至 onResume() 之后或子线程。

  • 主题预加载:使用 windowBackground 避免白屏。


8. 总结

Activity 的启动流程是 Android 系统设计的核心体现,涵盖 IPC 通信、进程管理、组件生命周期、界面渲染 等多个维度。理解此流程有助于:

  • 性能调优:定位启动耗时瓶颈。

  • 问题排查:分析 ANR、界面卡顿等问题的根因。

  • 系统定制:修改 AMS 或 ActivityThread 逻辑实现特殊需求(如插件化、多任务管理)。


http://www.ppmy.cn/devtools/164213.html

相关文章

基于机器学习的结构MRI分析:预测轻度认知障碍向阿尔茨海默病的转化

摘要 阿尔茨海默病是一种致残性神经退行性疾病,目前尚无有效的治疗方法。预测阿尔茨海默病的诊断对患者的预后至关重要,但目前的阿尔茨海默病生物标志物检测方法具有侵入性、耗时且昂贵。因此,开发基于MRI的计算方法用于阿尔茨海默病的早期诊…

RISC-V汇编学习(一)—— 基础认识

最近这三年的工作时间大部分的工作,都是基于riscv的cpu和接口ip开发适配驱动,时不时的就要debug测试代码,面对很多都是汇编,所以也是整理下积累的一点点笔记,系列博客将总结下riscv相关的内容,一是给有需要…

【Unity精品源码】Ultimate Character Controller:高级角色控制器完整解决方案

📂 Unity 开发资源汇总 | 插件 | 模型 | 源码 💓 欢迎访问 Unity 打怪升级大本营 在Unity游戏开发的世界中,角色控制器是构建游戏互动性的核心组件之一。Ultimate Character Controller是一款专为Unity引擎设计的高级角色控制器,它…

python中单例模式介绍(含线程安全的单例模式)

理解单例模式之前,确实需要先掌握 __init__、__new__ 和 __call__ 这三个方法的作用和调用顺序。如有需要,读者可跳转下方链接学习: python中的__init__、__new__、__call__-CSDN博客 正文开始: 在Python中,单例模式&…

Qt 文件操作+多线程+网络

文章目录 1. 文件操作1.1 API1.2 例子1,简单记事本1.3 例子2,输出文件的属性 2. Qt 多线程2.1 常用API2.2 例子1,自定义定时器 3. 线程安全3.1 互斥锁3.2 条件变量 4. 网络编程4.1 UDP Socket4.2 UDP Server4.3 UDP Client4.4 TCP Socket4.5 …

EMO模型详解及代码复现

EMO定义 EMO(Efficient Mobile Networks)是一种 面向移动端的轻量化网络模型 ,旨在 在参数、FLOPs和性能之间实现平衡 ,特别适用于 密集预测任务 。EMO的设计理念源于对CNN和Transformer架构的深入理解,通过整合两者的优势,实现了高效的模型性能。 EMO的核心是 反向残差…

【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第2章OpenHarmony v3.2-Beta4版本测试

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

playwright 自动化登录验证码,测试Iframe

还记得之前的文章吗,我们之前有说过,实现自动登录,详细分析了Playwright实战中登录状态问题。下面聚焦到storageState从原理到实战实现登录状态管理,从而一劳永逸解决验证码问题。 简介:在自动化测试中,频…