Android面试题——掘金-性能优化之启动优化(4.1)

一 概述

1
Android 性能优化相关面试题:启动优化

二 面试题解答(仅供参考)

2.1 什么是应用启动优化?为什么要优化?

1
2
3
4
5
6
7
8
9
10
11
12
1.应用启动优化是 
减少应用冷启动、热启动、温启动的耗时,提高用户体验,避免 白屏、卡顿、掉帧 等问题。

2.启动类型:
-冷启动(Cold Start):进程未启动,系统从头创建 Application,初始化资源,加载 UI(最慢)。
-热启动(Hot Start):应用进程仍在后台,直接恢复 UI(最快)。
-温启动(Warm Start):进程存在,但 Activity 需要重新创建(中等速度)。

3.目标:
✅ 降低冷启动时间(<1s 最佳)
✅ 减少主线程阻塞,提高帧率(避免卡顿)
✅ 减少不必要的初始化(Lazy Init)

2.2 如何分析应用启动时间?

1
2
3
4
5
6
7
8
9
1.ADB 命令(获取启动时间):adb shell am start -S -W com.example.app
关键指标:
-TotalTime:总启动时间
-WaitTime:从点击到 UI 响应时间
-ThisTime:当前 Activity 启动时

2.Android Studio Profiler(分析 Trace 数据)
-System Trace(全面分析)
-Startup Timing(分析 onCreate、onStart、onResume 耗时)

2.3 如何优化应用启动时间?

1-减少 Application 初始化时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.问题:Application#onCreate() 过多初始化,导致启动变慢
2.优化方案:
2.1 懒加载(Lazy Init):推迟初始化到 SplashActivity 或后台任务
2.2 异步初始化(Async Init)
GlobalScope.launch {
initSDKs() // 后台初始化 SDK
}
2.3 多进程初始化
if (ProcessUtils.isMainProcess(this)) {
initMainProcess() // 仅主进程初始化
}
2.4 使用 App Startup(Jetpack 库)
class MyInitializer : Initializer<MySDK> {
override fun create(context: Context): MySDK {
return MySDK.init(context) // 延迟初始化
}
}

2-减少 Activity/Fragment 初始化时间

1
2
3
4
5
6
7
8
9
10
11
12
1.问题:onCreate() 加载数据过多,阻塞主线程。
2.优化方案
2.1 View 预加载(Placeholder)
<ProgressBar android:visibility="visible" />
2.2 RecyclerView 使用 setHasFixedSize(true) 提高渲染效率
2.3 异步加载数据(如数据库、网络请求)
lifecycleScope.launch {
val data = withContext(Dispatchers.IO) { loadData() }
updateUI(data)
}
2.4 减少 findViewById,使用 ViewBinding
val binding = ActivityMainBinding.inflate(layoutInflater)

3-优化布局层级,减少 View 复杂度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.优化布局层级,减少 View 复杂度
2.优化方案
2.1 使用 ConstraintLayout 代替 LinearLayout 嵌套
2.2 减少不必要的 ViewGroup
2.3 使用 include 复用布局
2.4 使用 merge 减少 View 层级
<merge>
<TextView ... />
<Button ... />
</merge>
2.5 使用 AsyncLayoutInflater 预加载布局
AsyncLayoutInflater(this).inflate(R.layout.activity_main, null) { view, _, _ ->
setContentView(view)
}

4-优化资源加载

1
2
3
4
5
6
1.问题:大图片、文件 IO 操作占用启动时间。
2.优化方案:
-使用 VectorDrawable 代替 PNG
-使用 WebP 格式代替 PNG/JPG
-减少不必要的资源文件
-使用 Lottie 动画替代 GIF

5-优化 Dex 加载(MultiDex 影响启动速度)

1
2
3
4
5
6
7
8
9
10
11
12
13
1.问题:方法数超 65536,导致 Dex 分包,影响启动速度
2.优化方案:
2.1 开启 MultiDex(API < 21 必须)
multiDexEnabled true
2.2 使用 ProGuard / R8 代码优化
minifyEnabled true
2.3 启用 Dex Preloading(减少冷启动时间)
dexOptions {
preDexLibraries = true
}
2.4 使用 StartupOptimizer 预加载类
val optimizer = StartupOptimizer()
optimizer.prefetchClasses()

6-优化数据库、文件 IO

1
2
3
4
5
6
7
1.问题:SQLite / Room 查询慢,阻塞主线程
2.优化方案:
2.1 使用 Room 代替 SQLiteOpenHelper
2.2 数据库操作放入 IO 线程
val users = withContext(Dispatchers.IO) { userDao.getAllUsers() }
2.3 使用 MMKV 代替 SharedPreferences
MMKV.defaultMMKV().putString("key", "value")

7-优化线程调度

1
2
3
4
5
6
1.问题:主线程阻塞,影响 UI 渲染。
2.优化方案:
-2.1 使用 Dispatchers.IO 处理耗时任务
-2.2 使用 HandlerThread 或 Coroutines 代替 AsyncTask
-2.3 避免 StrictMode 违规
StrictMode.setThreadPolicy(ThreadPolicy.Builder().detectAll().penaltyLog().build())

2.4 启动优化的最佳实践

1
2
3
4
5
6
7
✅ Application 不要做重初始化,推迟 SDK 加载
✅ 使用 Lazy Init + Jetpack Startup
✅ 减少 XML 复杂度,优化布局层级
✅ 使用 RecyclerView + ViewBinding 加快 UI 初始化
✅ Dex 优化,减少 MultiDex 影响
✅ 异步加载数据,避免主线程阻塞
✅ 数据库 Room、存储 MMKV 代替 SharedPreferences

2.5 总结

1
2
3
4
5
6
7
Android 启动优化 的核心目标是 减少 Application 初始化、优化布局、优化资源加载、优化 IO 线程:

-减少 Application 初始化(Lazy Init / Jetpack Startup)
-减少 View 层级(ConstraintLayout / AsyncLayoutInflater)
-优化 Dex 加载(MultiDex、ProGuard)
-优化数据库 / 文件 IO(Room / MMKV)
-优化线程调度(避免主线程阻塞)

三 参考

  • 掘金—知识库的大纲