Android应用启动优化详解
应用启动速度是用户体验的关键指标,优化启动速度可以显著提升用户留存率。
启动类型
1. 冷启动(Cold Start)
- 定义:应用完全从零开始启动
- 过程:创建进程 → 初始化Application → 启动主Activity → 布局加载 → 首帧绘制
- 耗时:最长,需要优化重点
2. 热启动(Hot Start)
- 定义:应用从后台切换到前台
- 过程:直接恢复Activity
- 耗时:最短
3. 温启动(Warm Start)
- 定义:介于冷启动和热启动之间
- 场景:进程被杀死但Activity实例仍被系统保留
启动流程分析
shell冷启动完整流程: Click Launcher Icon ↓ Zygote Fork App Process (约100-200ms) ↓ ActivityThread.main() ↓ Application.attachBaseContext() ↓ Application.onCreate() ← 优化重点 ↓ Activity.onCreate() ↓ Activity.onStart() ↓ Activity.onResume() ↓ ViewRootImpl.performTraversals() ↓ First Frame Drawn ← 启动完成
启动优化策略
1. Application优化
延迟初始化
kotlinclass MyApplication : Application() { override fun onCreate() { super.onCreate() // 避免在主线程同步初始化 // 使用异步或延迟初始化 } }
使用ContentProvider延迟初始化
kotlinclass InitProvider : ContentProvider() { override fun onCreate(): Boolean { // 初始化第三方SDK return true } }
2. 异步初始化
kotlin// 使用线程池异步初始化 val executor = Executors.newFixedThreadPool(4) executor.execute { // 初始化非必要SDK Bugly.init() PushService.init() }
3. 使用Startup库
kotlin// 定义初始化任务 class WorkManagerInitializer : Initializer<WorkManager> { override fun create(context: Context): WorkManager { return WorkManager.getInstance(context) } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
4. 布局优化
减少布局层级
xml<!-- 使用ConstraintLayout减少嵌套 --> <androidx.constraintlayout.widget.ConstraintLayout> <!-- 扁平化布局 --> </androidx.constraintlayout.widget.ConstraintLayout>
延迟加载非首屏布局
kotlin// 使用ViewStub viewStub.inflate()
异步Inflate
kotlin// 使用AsyncLayoutInflater AsyncLayoutInflater(this).inflate(R.layout.activity_main, null) { view, _, _ -> setContentView(view) }
5. 类加载优化
Dex预加载
kotlin// 在Application中预加载常用类 Class.forName("com.example.MainActivity")
避免使用反射
- 反射调用耗时
- 使用APT生成代码替代
6. 黑白屏优化
设置Window背景
xml<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowFullscreen">true</item> </style>
使用预览窗口(Android 12+)
xml<item name="android:windowSplashScreenBackground">@color/splash_background</item> <item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
启动时间测量
1. 系统日志
shelladb logcat -s ActivityManager | grep "Displayed" // 输出:Displayed com.example/.MainActivity: +1s234ms
2. Systrace
shellpython systrace.py -a com.example -o trace.html
3. 代码打点
kotlinclass MyApplication : Application() { override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) Log.d("Startup", "attachBaseContext: ${System.currentTimeMillis()}") } }
面试要点
- 理解冷启动、热启动的区别
- 掌握Application和Activity的启动流程
- 熟悉异步初始化和延迟加载策略
- 了解Systrace和Profiler的使用
- 掌握黑白屏优化方案