1. 课程导入
Android Framework 是连接应用与 Linux 内核的“中枢层”,它既承载 Activity、Window、Package、AMS、WMS 等系统服务,又直接决定应用启动速度、滑动流畅度、内存水位与系统稳定性。很多开发者遇到卡顿、ANR、Crash、内存泄漏时,第一反应是查应用代码,但真正的根因往往藏在 Binder 调用、SystemServer 锁竞争、SurfaceFlinger 合成、LowMemoryKiller 回收策略等 Framework 环节。本课程的目标,是让你从“会看日志”进阶到“能定位链路、能修改机制、能验证收益”。
一、核心概念:先建立 Framework 的坐标系
学习 Framework 优化,第一步不是背源码,而是建立分层坐标系。Android 系统大致分为应用层、Framework 层、Native 层与内核层。Framework 层内部又可细分为 Java 服务、JNI、Native 服务与 HAL 接口。性能问题通常表现为“上层现象”,但根因可能在下层。例如应用冷启动慢,可能是 Application 初始化耗时,也可能是 AMS 调度延迟、Binder 线程池阻塞,甚至 IO 抖动导致 dex2oat 变慢。
因此,本课程会反复使用四个核心概念:调用链、关键路径、资源竞争、观测点。调用链回答“谁调用了谁”;关键路径回答“哪一段最耗时”;资源竞争回答“谁在等谁”;观测点回答“用什么工具能看到”。只有把现象映射到调用链上的具体节点,优化才不是盲猜。
二、方法流程:从现象到根因的五步法
面对一个性能或稳定性问题,建议固定使用五步法,避免“上来就改代码”。
- 定义现象与指标:例如“冷启动 1.8s,目标 1.2s”“滑动 120 帧中掉 18 帧”“ANR 率 0.3%”。指标必须可量化、可复现。
- 抓取现场数据:使用 Perfetto、Systrace、logcat、dumpsys、traces.txt、tombstone 等,保留时间戳与进程信息。
- 还原调用链:把主线程、Binder 线程、RenderThread、SurfaceFlinger 的时间线对齐,找到阻塞点。
- 定位根因:区分是锁竞争、IO 等待、GC、CPU 抢占、Binder 超时还是逻辑错误。
- 修改与回归:小步修改,A/B 对比,确认指标改善且无副作用。
# 典型抓取命令示例
adb shell perfetto -o /data/misc/perfetto-traces/trace.pftrace \
-t 10s sched freq idle am wm gfx view binder_driver
adb shell dumpsys activity processes | grep -i "ANR"
adb shell cat /data/anr/traces.txt
adb shell dumpsys SurfaceFlinger --latency com.example.app
三、案例场景:一次滑动卡顿的排查路径
假设某应用在列表滑动时出现周期性卡顿。第一步看 Perfetto,发现主线程在 ViewRootImpl.performTraversals 中耗时 32ms,超过 16.6ms 帧预算。继续展开调用链,发现 measure 阶段触发了多次 requestLayout,同时 RenderThread 在等待 GPU 完成上一帧。再查 Binder,发现 WMS 的 relayoutWindow 被 SystemServer 中的锁阻塞。最终根因是窗口层级过深导致合成压力大,叠加主线程重复布局。修复方向包括:减少嵌套层级、复用 ViewHolder、把非关键布局放到异步线程、降低透明区域重叠。这个案例说明:卡顿不是“一个点”,而是主线程、RenderThread、SurfaceFlinger、WMS 共同作用的结果。
四、常见误区与复盘清单
初学者最容易陷入四个误区:一是只看应用代码,忽略系统服务;二是只看平均耗时,忽略尾延迟与抖动;三是只优化单点,破坏整体稳定性;四是修改后不做回归,导致问题转移。建议每完成一次优化,都用下表复盘。
| 复盘项 | 关键问题 | 输出物 |
|---|---|---|
| 现象定义 | 指标是否可量化、可复现? | 基线数据与目标值 |
| 数据抓取 | 是否覆盖主线程、Binder、RenderThread? | Perfetto / 日志 / traces |
| 根因定位 | 是等待、竞争还是计算? | 调用链与阻塞点 |
| 修改验证 | A/B 是否显著?有无副作用? | 对比报告与回归结论 |
本课程后续将沿着“启动优化、流畅度优化、内存优化、ANR 分析、Crash 与 Watchdog、Binder 与锁竞争、SystemServer 稳定性、Perfetto 实战”等主题逐步展开。每一节都会给出真实场景、可执行命令、调用链分析方法和验证思路。你需要做的,是带着一个具体问题进入每一节,用五步法把它拆开、定位、修复并回归。这样学完 30 章,你收获的不只是知识点,而是一套可复用的 Framework 优化方法论。