为什么性能优化如此重要?
根据 Google 的研究,如果应用启动时间超过 5 秒,用户放弃率会急剧上升。一个流畅的应用不仅提升用户体验,还直接影响应用商店的评分和留存率。
一、应用启动优化
冷启动 vs 温启动 vs 热启动
- 冷启动:应用进程被杀死后重新启动,耗时最长。
- 温启动:Activity 被销毁但进程还在,可能是 trimMemory 导致的。
- 热启动:Activity 仍驻留在内存中,最快。
优化手段
- 延迟初始化:将非首屏必须的第三方 SDK 放到 IdleHandler 或协程中延迟加载:
Looper.myLooper()?.queue?.addIdleHandler { HeavySdk.init() false // 只执行一次 } - 启动主题优化:使用 windowBackground 设置一个占位背景,避免白屏。
- 减少 Application.onCreate 的工作:只做最必要的初始化。
二、内存优化
常见内存泄漏场景
- 静态变量持有 Activity 引用
- 非静态内部类 / 匿名类隐式持有外部类引用
- Handler 消息未处理完
- 未取消的协程 / RxJava 订阅
- 单例持有 Context 引用(应该用 ApplicationContext)
检测工具
- Android Studio Memory Profiler
- LeakCanary:自动检测内存泄漏并给出引用链
- MAT (Memory Analyzer Tool):分析 hprof 文件
// LeakCanary 集成(仅需一行)
dependencies {
debugImplementation "com.squareup.leakcanary:leakcanary-android:2.12"
}
三、渲染优化
关键指标:16ms 帧
60fps 意味着每帧只有 16ms 的时间。任何超过这个时间的操作都会导致丢帧(jank)。
优化技巧
- 减少布局层级:使用 ConstraintLayout 替代嵌套的 LinearLayout。
- 使用 ViewStub:对不常显示的 View 延迟初始化。
- 避免过度绘制:在开发者选项中开启”显示过度绘制区域”。
- RecyclerView 优化:使用 setHasFixedSize(true)、DiffUtil、预取。
- 图片加载:使用 Glide/Coil,避免直接在 UI 线程解码位图。
总结
性能优化不是一蹴而就的。建议先通过 Profiler 找到瓶颈,再针对性优化。务必在优化前后做好数据对比,验证效果。