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

《Android APP 启动流程深度解析》

目录

一、流程对比图

二、冷启动(Cold Launch)

2.1 用户点击应用图标(Launcher 触发)

2.2 AMS 处理启动请求

2.3 请求 Zygote 创建新进程

2.4 初始化应用进程

2.5 创建 Application 对象

2.6 启动目标 Activity

2.7 执行 Activity 生命周期

2.8 UI 绘制流程

2.9 关键类与机制总结

2.10 冷启动优化:

三、热启动(Warm Launch)

3.1 详细流程:

3.2 热启动优化:

四、冷启动 vs 热启动对比

五、启动优化工具

六、空白window问题


一、流程对比图

以下为 冷启动 和 热启动 的流程对比图:


二、冷启动(Cold Launch)

定义:应用进程完全不存在,系统需从头创建进程并初始化组件。

APP冷启动时序图: 

详细流程

Android 应用冷启动流程是一个复杂的系统级协作过程,涉及多个关键组件和源码模块。以下是详细的流程解析及源码分析:


2.1 用户点击应用图标(Launcher 触发)

  • Launcher 是一个特殊的 Android 应用,负责管理主屏幕和应用快捷方式。

  • 点击图标时,Launcher 通过 startActivity() 发起启动请求。目标 Activity 的 Intent 会被设置为 FLAG_ACTIVITY_NEW_TASK,表示新任务栈。

源码关键点

  • Launcher 调用 startActivitySafely(),最终通过 Instrumentation.execStartActivity() 发起请求。


2.2 AMS 处理启动请求

  • ActivityManagerService (AMS) 是 Android 核心服务,负责管理 Activity 生命周期和任务栈。

  • AMS 检查目标 Activity 是否存在、权限是否满足,并决定是否创建新进程。

源码路径

  • 请求通过 Binder 传递到 ActivityManagerService.startActivity()

  • 关键类:ActivityStarter 处理启动逻辑,ActivityStackSupervisor 管理任务栈。


2.3 请求 Zygote 创建新进程

  • 如果目标应用未运行,AMS 通过 Zygote 进程 fork 出新进程。

  • Zygote 预加载了常用类库和资源,加快进程创建速度。

源码关键点

  • ZygoteProcess.start() 通过 Socket 与 Zygote 通信,发送参数(如主类 android.app.ActivityThread)。

  • 新进程入口:ActivityThread.main()


2.4 初始化应用进程

  • ActivityThread 是应用进程的主线程类,负责管理应用组件的生命周期。

源码流程

  1. 入口方法ActivityThread.main() 初始化主线程 Looper。

    public static void main(String[] args) {
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false); // 关联到 AMS
        Looper.loop();
    }
  2. 绑定到 AMS:通过 attach() 方法,跨进程调用 AMS.attachApplication(),传递 ApplicationThread(Binder 对象,用于 AMS 回调)。


2.5 创建 Application 对象

  • AMS 通知新进程创建 Application 实例,并调用其 onCreate()

源码关键点

  • ActivityThread.handleBindApplication() 处理 AMS 的绑定请求:

    private void handleBindApplication(AppBindData data) {
        // 1. 创建 LoadedApk(封装 APK 信息)
        LoadedApk loadedApk = getLoadedApk(data.appInfo);
        // 2. 创建 ContextImpl
        ContextImpl appContext = ContextImpl.createAppContext(this, loadedApk);
        // 3. 创建 Instrumentation
        Instrumentation instr = new Instrumentation();
        // 4. 创建 Application 实例
        Application app = loadedApk.makeApplication(false, instr);
        // 5. 调用 Application.onCreate()
        instr.callApplicationOnCreate(app);
    }

2.6 启动目标 Activity

  • AMS 通过 ApplicationThread 调度启动目标 Activity。

源码流程

  1. AMS 发送启动请求ActivityStackSupervisor.realStartActivityLocked()

  2. 进程内处理ActivityThread.scheduleLaunchActivity() 发送 LAUNCH_ACTIVITY 消息到主线程 Handler(H)。

  3. 创建 Activity 实例ActivityThread.handleLaunchActivity()

    private void handleLaunchActivity(ActivityClientRecord r) {
        // 1. 创建 Activity 实例
        Activity activity = mInstrumentation.newActivity(cl, component, r.intent);
        // 2. 创建 Application 和 ContextImpl
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ContextImpl appContext = createBaseContextForActivity(r);
        // 3. 关联 Activity 和 Context
        activity.attach(appContext, this, ...);
        // 4. 调用 Activity.onCreate()
        mInstrumentation.callActivityOnCreate(activity, r.state);
        // 5. 执行 onStart() 和 onResume()
        handleStartActivity() -> handleResumeActivity();
    }

2.7 执行 Activity 生命周期

  • Instrumentation 负责监控 Activity 生命周期调用。

  • 关键生命周期回调顺序:onCreate() → onStart() → onResume()

源码关键点

  • ActivityThread.performLaunchActivity() 触发 onCreate()

  • ActivityThread.handleResumeActivity() 触发 onResume(),并添加 ViewRootImpl 启动 UI 绘制。


2.8 UI 绘制流程

  • ViewRootImpl 负责管理 UI 渲染,触发 measure() → layout() → draw()

  • Activity 变为可见状态后,onWindowFocusChanged(true) 被调用。


2.9 关键类与机制总结

  • Zygote:进程孵化器,加速进程创建。

  • AMS:全局管理 Activity 和进程。

  • ActivityThread:应用主线程,管理组件生命周期。

  • ApplicationThread:Binder 桥梁,用于 AMS 与应用进程通信。

  • Instrumentation:监控和控制组件生命周期。


2.10 冷启动优化

  • 减少 Application.onCreate() 耗时操作:避免在主线程初始化第三方库。

  • 避免主线程阻塞,优化首帧渲染时间(如减少布局层级)。

  • 使用启动主题:替换默认白屏/黑屏,提升用户体验(如设置 windowBackground)。

  • 延迟加载:按需初始化非关键组件(如使用 SplashScreen)。


三、热启动(Warm Launch)

定义:应用进程仍在后台运行(未被系统回收),直接复用已有进程。

3.1 详细流程

  1. 用户触发
    用户从最近任务列表或返回应用。

  2. 恢复 Activity

    • 若主 Activity 未被销毁,直接调用 Activity.onRestart() → onStart() → onResume()

    • 若 Activity 被销毁但进程存活,重建 Activity(调用 onCreate())。

  3. 界面切换

    • WindowManager 将后台 Activity 切换到前台,无需重新布局。

3.2 热启动优化

  • 避免内存泄漏:防止 Activity 无法回收导致进程驻留。

  • 精简 onResume() 逻辑:减少重复初始化操作。

  • 使用 ViewModel:缓存界面数据,避免重复加载。


四、冷启动 vs 热启动对比

特性冷启动热启动
进程状态进程不存在,需从头创建进程已存在,直接复用
耗时较长(100ms~数秒)较短(通常 <100ms)
资源消耗高(CPU、内存)
生命周期调用Application.onCreate() → Activity.onCreate()Activity.onRestart()→ onResume()

五、启动优化工具

  1. ADB 命令

    adb shell am start -W <package>/<activity>

    输出 TotalTime 和 WaitTime 分析启动耗时。

  2. Android Profiler
    监控 CPU、内存和线程状态,定位耗时操作。

  3. Jetpack Macrobenchmark
    自动化测试启动性能并生成报告。


六、空白window问题

app启动时,会短暂的一瞬间白屏:

有两种方法:
1. 禁用app启动时window预览的功能
在主题中为首屏activity添加一个注意禁用window预览的功能,并在manifest中使用

<resources>
    <!--Base application theme-->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!--Customize your theme here.-->
        <item name="colorPrimary">@color/mainColor</item>
        <item name="colorPrimaryDark">@color/red</item>
        <item name="colorAccent">@color/black</item>
    </style>

    <!--禁用预览功能主题-->
    <style name="AppSpalshNoPreviewTheme" parent="AppTheme">
    	<item name="android:windowFullscreen">true</item>
        <item name="windowNoTitle">true</item>
    
        <!--        <item name="android:windowBackground">@mipmap/wall</item>-->
        <item name="android:windowDisablePreview">true</item>
    </style>
</resources>

2. 给空白首屏Activity设置一个背景
在style.xml中给SplashActivity添加一个新主题,设置一个背景:

    <style name="AppSpalshNoPreviewTheme" parent="AppTheme">
        <item name="android:windowFullscreen">true</item>
        <item name="windowNoTitle">true</item>

        <item name="android:windowBackground">@mipmap/aliyun</item>
        <!--        <item name="android:windowDisablePreview">true</item>-->
    </style>

会发现点击后,之前的空白页面换成了背景图

冷启动的介绍可知,app启动过程中,会有如下过程

app启动过程中,显示白屏,首屏第一次绘制完成,就会替换白屏;也就是说在首屏显示之前,都是白屏。所以,要想解决白屏的问题,就要减少白屏显示的时间,也就是说要加快app初始化和首屏绘制的时间。


通过理解冷/热启动机制及优化方法,可显著提升用户体验。如果喜欢,欢迎点赞!

参考:

1. android系统_app冷启动流程分析

2. Android中的冷启动,热启动和温启动

相关文章:

  • PostgreSQL-01-入门篇-简介
  • 天梯选拔赛赛后补题
  • 一键装数据库脚本3分钟极速部署,传统耗时砍掉95%!
  • 基于STM32的逻辑分析仪
  • MoonSharp 文档二
  • 蓝桥杯FPGA-ds1302驱动
  • 九点标定和十二点标定的区别
  • 【问题记录】如何编译nv_peer_memory模块?依赖OFED的4个目录和2类文件?如何解决没有rdma/peer_mem.h文件?
  • Python 远程抓取服务器日志最后 1000行
  • Vue3 路由的历史记录 如何不允许浏览器前进后退 在函数中使用路由切换组件 路由的重定向
  • 鸿基智启:东土科技为具身智能时代构建确定性底座
  • 英国赫瑞瓦特大学激光雷达领域研究概述2025.3.11
  • 计算机毕业设计:公寓管理系统
  • Ubuntu本地部署Open manus(完全免费可用)
  • 【OpenCV C++】存图,如何以时间命名,“年月日-时分秒“产生唯一的文件名呢?“年月日-时分秒-毫秒“ 自动检查存储目录,若不存在自动创建存图
  • FB投广探秘:为何Facebook广告账户不消耗
  • Unity安卓Android从StreamingAssets加载AssetBundle
  • Redis的高可用
  • 深入解析K8s VolumeMounts中的subPath字段及其应用
  • 怎么使用数据集微调大模型LLM
  • 成都pc网站建设/阿里巴巴官网
  • 网站 备案 哪个省/搜狗站长平台主动提交
  • 做外汇关注的网站/小辉seo
  • 网站如何备案工信局/台州关键词优化报价
  • 网站建设属于什么行业/优化公司结构
  • 东莞疫情最新消息虎门/长春seo整站优化