目录
一、流程对比图
二、冷启动(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 是应用进程的主线程类,负责管理应用组件的生命周期。
源码流程:
-
入口方法:
ActivityThread.main()
初始化主线程 Looper。public static void main(String[] args) {Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false); // 关联到 AMSLooper.loop(); }
-
绑定到 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. 创建 ContextImplContextImpl appContext = ContextImpl.createAppContext(this, loadedApk);// 3. 创建 InstrumentationInstrumentation instr = new Instrumentation();// 4. 创建 Application 实例Application app = loadedApk.makeApplication(false, instr);// 5. 调用 Application.onCreate()instr.callApplicationOnCreate(app); }
2.6 启动目标 Activity
-
AMS 通过
ApplicationThread
调度启动目标 Activity。
源码流程:
-
AMS 发送启动请求:
ActivityStackSupervisor.realStartActivityLocked()
。 -
进程内处理:
ActivityThread.scheduleLaunchActivity()
发送LAUNCH_ACTIVITY
消息到主线程 Handler(H
)。 -
创建 Activity 实例:
ActivityThread.handleLaunchActivity()
:private void handleLaunchActivity(ActivityClientRecord r) {// 1. 创建 Activity 实例Activity activity = mInstrumentation.newActivity(cl, component, r.intent);// 2. 创建 Application 和 ContextImplApplication app = r.packageInfo.makeApplication(false, mInstrumentation);ContextImpl appContext = createBaseContextForActivity(r);// 3. 关联 Activity 和 Contextactivity.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 详细流程:
-
用户触发
用户从最近任务列表或返回应用。 -
恢复 Activity
-
若主 Activity 未被销毁,直接调用
Activity.onRestart()
→onStart()
→onResume()
。 -
若 Activity 被销毁但进程存活,重建 Activity(调用
onCreate()
)。
-
-
界面切换
-
WindowManager
将后台 Activity 切换到前台,无需重新布局。
-
3.2 热启动优化:
-
避免内存泄漏:防止 Activity 无法回收导致进程驻留。
-
精简
onResume()
逻辑:减少重复初始化操作。 -
使用
ViewModel
:缓存界面数据,避免重复加载。
四、冷启动 vs 热启动对比
特性 | 冷启动 | 热启动 |
---|---|---|
进程状态 | 进程不存在,需从头创建 | 进程已存在,直接复用 |
耗时 | 较长(100ms~数秒) | 较短(通常 <100ms) |
资源消耗 | 高(CPU、内存) | 低 |
生命周期调用 | Application.onCreate() → Activity.onCreate() | Activity.onRestart() → onResume() |
五、启动优化工具
-
ADB 命令
adb shell am start -W <package>/<activity>
输出
TotalTime
和WaitTime
分析启动耗时。 -
Android Profiler
监控 CPU、内存和线程状态,定位耗时操作。 -
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中的冷启动,热启动和温启动