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

Android13 Activity启动流程深度解析:从进程间通信到窗口树构建

1. Android13 Activity启动流程概述

Activity启动是Android应用开发中最基础也最核心的机制之一。在Android 13中,这个流程涉及多个系统进程的协作,主要包括:

  • 应用进程:发起Activity启动请求
  • SystemServer进程:通过ActivityTaskManagerService(ATMS)协调启动过程
  • Zygote进程:孵化新应用进程
  • WindowManagerService:管理窗口和显示层级

整个启动流程可以概括为7个关键步骤:

  1. 应用进程通过Binder调用ATMS发起startActivity请求
  2. ATMS检查目标Activity的进程是否存在
  3. 若进程不存在,通过Zygote fork新进程
  4. 新进程初始化后向ATMS注册
  5. ATMS通过Binder通知新进程创建目标Activity
  6. 应用进程的主线程完成Activity实例化
  7. WindowManager构建窗口树并显示Activity

2. 进程间通信机制

2.1 Binder通信框架

Android使用Binder实现跨进程通信,Activity启动流程中涉及的主要Binder接口:

// 客户端接口 public interface IActivityTaskManager { int startActivity(IApplicationThread caller, String callingPackage, Intent intent, ...); } // 服务端实现 public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // 实现Binder接口方法 }

关键通信过程:

  1. 应用进程通过ActivityTaskManager.getService()获取ATMS的Binder代理
  2. 调用startActivity()方法发起请求
  3. ATMS处理请求后通过IApplicationThread回调应用进程

2.2 数据传输对象

跨进程传递的主要数据结构:

  • ActivityRecord:系统服务端维护的Activity描述
  • ActivityClientRecord:客户端维护的Activity描述
  • Task:Activity任务栈的抽象
  • WindowContainer:窗口容器基类

3. 窗口管理系统

3.1 窗口树结构

Android 13的窗口管理系统采用树形结构组织:

RootWindowContainer ├── DisplayContent (物理显示屏) │ ├── TaskDisplayArea (应用窗口区域) │ │ ├── Task (任务栈) │ │ │ ├── ActivityRecord │ │ │ │ └── WindowState │ │ └── ImeContainer (输入法窗口) └── Tokens (特殊类型窗口)

3.2 关键类解析

  • RootWindowContainer:窗口树的根节点
  • DisplayContent:对应物理显示屏,支持多屏显示
  • Task:管理一组相关的Activity,维护回退栈
  • ActivityRecord:系统服务端对Activity的抽象
  • WindowState:对应一个具体的窗口

4. 启动流程详细解析

4.1 发起启动请求

应用进程调用流程:

// Activity.java public void startActivity(Intent intent) { getInstrumentation().execStartActivity( this, mMainThread.getApplicationThread(), mToken, intent); } // Instrumentation.java public ActivityResult execStartActivity(...) { int result = ActivityTaskManager.getService() .startActivity(whoThread, callingPackage, intent, ...); checkStartActivityResult(result, intent); }

4.2 SystemServer处理流程

ATMS核心处理逻辑:

// ActivityTaskManagerService.java public int startActivity(IApplicationThread caller, ...) { // 1. 创建ActivityRecord final ActivityRecord r = new ActivityRecord(...); // 2. 获取或创建目标Task final Task targetTask = computeTargetTask(); // 3. 启动目标进程(如果需要) startProcessAsync(...); // 4. 调度Activity启动 mStackSupervisor.realStartActivityLocked(r, ...); }

4.3 进程创建过程

Zygote进程孵化新进程:

  1. ATMS通过Socket连接Zygote
  2. Zygote fork出新进程
  3. 新进程执行ActivityThread.main()
  4. 初始化应用环境并绑定到ATMS

4.4 Activity实例化

客户端创建Activity的流程:

// ActivityThread.java private Activity performLaunchActivity(ActivityClientRecord r) { // 1. 创建Activity实例 Activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); // 2. 创建Application(如果不存在) Application app = r.packageInfo.makeApplication(false, null); // 3. 关联Context和Window activity.attach(appContext, this, getInstrumentation(), r.token, ...); // 4. 回调onCreate() mInstrumentation.callActivityOnCreate(activity, r.state); return activity; }

5. 窗口构建与显示

5.1 窗口创建流程

// Activity.java final void attach(Context context, ...) { // 创建PhoneWindow实例 mWindow = new PhoneWindow(this, window, ...); mWindow.setWindowManager(...); } // PhoneWindow.java public void setContentView(View view) { installDecor(); mLayoutInflater.inflate(layoutResID, mContentParent); }

5.2 窗口添加到WM

// ActivityThread.java public void handleResumeActivity(IBinder token, ...) { // 1. 回调onResume() final ActivityClientRecord r = performResumeActivity(token, ...); // 2. 获取WindowManager View decor = r.window.getDecorView(); WindowManager.LayoutParams l = r.window.getAttributes(); // 3. 添加窗口到WMS wm.addView(decor, l); }

6. 性能优化实践

6.1 启动耗时分析

关键耗时阶段:

  • 进程创建:约100-300ms
  • Application初始化:依赖业务逻辑
  • Activity创建:约50-150ms
  • 首帧绘制:依赖布局复杂度

6.2 优化建议

  1. 避免冷启动

    • 使用预加载进程
    • 合理设置android:process
  2. 简化Application

    • 延迟初始化非必要组件
    • 使用App Startup库
  3. 优化布局

    • 减少布局层级
    • 使用ViewStub延迟加载
  4. 多线程初始化

    // 使用IntentService或线程池初始化 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { // 后台初始化代码 });

7. 常见问题排查

7.1 启动白屏问题

解决方案:

<!-- styles.xml --> <style name="AppTheme.Launcher"> <item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowFullscreen">true</item> </style>

7.2 跨进程启动失败

检查要点:

  1. AndroidManifest中是否声明Activity
  2. 是否满足exported要求
  3. 进程权限是否配置正确
  4. 跨用户启动需要特殊权限

7.3 窗口层级问题

调试命令:

adb shell dumpsys window windows

输出示例:

Window #7: Window{xxx u0 com.example.app/...} mOwnerUid=10123 mShowToOwnerOnly=true mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#1820002 pfl=0x20000}
http://www.cnnetsun.cn/news/2005970.html

相关文章:

  • 从电位器到内部温度传感器:一个STM32 ADC多通道采集的完整项目实战(含代码与波形分析)
  • 【效率革命】18款免费3dMAX插件与脚本,解锁你的创意生产力
  • 【Qwen3.5 系列技术解析】:2026 年原生多模态旗舰模型全景报告
  • 告别Command Not Found:手把手教你配置Mac上的zsh与Oh My Zsh(含Homebrew、zsh-autosuggestions插件安装)
  • 保姆级教程:在Ubuntu 20.04上搞定Velodyne VLP-16雷达的ROS驱动与Rviz可视化(含网络配置避坑)
  • 武汉大学计算机复试通关指南:从机考到面试的实战策略
  • TypeScript的NonNullable《T》工具类型的实现原理
  • RWKV-7 (1.5B World)多场景落地:教育问答、跨境客服、内容创作三合一
  • 频谱分析避坑指南:为什么你补了零却提不高频率分辨率?
  • 从SENet到CBAM:通道注意力机制的‘进化史’与实战调参指南
  • 【企业级向量安全红线】:EF Core 10中必须禁用的5个默认配置、4类危险LINQ表达式及3种合规审计Checklist
  • Qt Widgets模块实战:QGridLayout栅格布局从入门到精通
  • Simulink数据管理踩坑记:为什么我们最终放弃了.sldd,改用Excel管理标定量?
  • Arduino新手必看:用ULN2003驱动28BYJ-48步进电机的完整指南(附代码)
  • Elasticsearch 向量数据库指南
  • 题解:洛谷 P1321 单词覆盖还原
  • 题解:洛谷 P1789 【Mc生存】插火把
  • 微信搜狗助手项目教程
  • PyTorch LSTM实战:当‘直接多输出’遇上真实业务,我是如何权衡预测步长与精度的
  • PyTorch实战:用pack_padded_sequence搞定RNN变长输入,别再让padding影响你的模型效果了
  • 终极指南:如何用stacktrace.js构建企业级前端错误监控系统
  • 企业级云原生平台实战指南:Tsuru服务网格部署的完整解决方案
  • 别慌!2026毕业季‘学术焦虑症’,百考通AI给你开处方
  • 解放双手的智能游戏助手:MaaYuan如何帮你高效管理《代号鸢》与《如鸢》日常任务?
  • 终极对比:BigImageViewer vs PhotoDraweeView vs FrescoImageViewer 深度评测
  • 告别Unity AudioSource!用FMOD Studio 2.02打造专业级游戏音效(附完整Unity 2022配置流程)
  • 如何从零部署Colanode:开源协作平台的完整生产环境搭建指南
  • debug驱动学习——三次debug改变我的技术认知
  • Unity网络开发革命:Netcode for GameObjects完整入门指南
  • Material Icon Library多主题适配:实现白天/黑夜模式的图标切换