Android稳定性-02-Android 系统架构:从 App 到 Kernel 的调用链

做 Android 系统稳定性测试时,最容易犯的错误,是把问题只看成一个表层现象。

比如:

  • 应用闪退了,就只看应用日志
  • 页面卡住了,就只怀疑 UI 自动化脚本不稳定
  • 设备黑屏了,就只截图留证
  • 系统重启了,就只说“机器不稳定”
  • Monkey 跑出了 ANR,就只把 ANR traces 发给开发

这些动作不是没用,但如果测试同学对 Android 系统架构没有基本认知,很容易只停在“发现问题”和“转交日志”这一步。真正难的是继续往下判断:

  • 这是 App 自己的问题,还是 Framework 服务异常
  • 是主线程卡住,还是 Binder 调用链路卡住
  • 是 Window、Input、Display、SurfaceFlinger 这一层的问题,还是底层驱动问题
  • 是 Native Service 崩了,还是 HAL 返回异常
  • 是 system_server 卡死,还是 Kernel 触发了 panic

所以 Android 稳定性测试不能只会跑 Monkey、抓 logcat、导 bugreport。至少要先把一条基本链路讲清楚:

一个 App 发起动作后,系统从 App 到 Framework、System Server、Native Service、HAL、Kernel、驱动大致是怎么协作的。

这篇文章就从稳定性测试视角,把这条调用链拆开。

一、先建立一张简化架构图

Android 系统可以先粗略拆成下面几层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
App 层
|
| Java / Kotlin API
v
Framework 层
|
| Binder IPC
v
System Server / 系统服务
|
| Binder / Socket / Native 调用
v
Native Service / 系统 Native 组件
|
| HIDL / AIDL HAL / JNI / ioctl / sysfs
v
HAL 层
|
| 驱动接口
v
Kernel / Driver 层
|
v
硬件

这张图很简化,但对测试定位已经够用了。

因为大多数稳定性问题,最后都能放回这几层里判断:

  • App 层:业务代码、三方 SDK、主线程、资源使用、生命周期
  • Framework 层:Android 对外暴露的系统能力和 Java API
  • System Server:Activity、Window、Package、Power、Input、Display 等核心系统服务
  • Native Service:SurfaceFlinger、AudioFlinger、media、netd、vold、servicemanager 等 Native 组件
  • HAL 层:相机、音频、传感器、蓝牙、定位、显示等硬件抽象接口
  • Kernel / Driver 层:进程调度、内存、文件系统、网络、Binder 驱动、设备驱动

稳定性测试看这张图,不是为了背架构,而是为了形成一个判断习惯:

看到现象后,先判断它最可能发生在哪一层,再决定优先看什么日志。

二、App 层:稳定性问题最容易被看到的地方

App 层是测试最容易接触的一层。

比如:

  • 点击某个页面后闪退
  • 某个按钮无响应
  • 页面加载很慢
  • 切后台再回来白屏
  • Monkey 随机点出 Crash
  • 长时间运行后内存持续上涨

这些现象都发生在 App 表面,但根因不一定都在 App。

App 层最常见的问题包括:

  • Java Crash
  • Native Crash
  • ANR
  • 主线程阻塞
  • 内存泄漏
  • 线程泄漏
  • 文件描述符泄漏
  • 生命周期处理错误
  • 权限或系统能力调用异常
  • 三方 SDK 异常

如果只是普通 App 测试,看到 App 崩溃,通常先看 logcat 里的 FATAL EXCEPTION。但系统稳定性测试要多问一步:

这个 App 异常有没有触发系统服务异常,或者是不是由系统服务异常导致的?

比如相机应用打开失败,可能是 App 自己逻辑错,也可能是:

  • CameraService 异常
  • camera provider 异常
  • camera HAL 异常
  • 驱动返回错误
  • 权限状态异常
  • 设备资源被占用

所以 App 层日志是入口,但不能天然等于根因。

常用观察命令:

1
2
3
4
5
adb shell ps -A
adb shell top
adb shell dumpsys activity top
adb shell dumpsys meminfo <package>
adb logcat -b all -v threadtime

测试判断重点:

  • 目标进程是否还在
  • 是否出现 FATAL EXCEPTION
  • 是否出现 ANR in <package>
  • 主线程是否阻塞在 Binder、锁、I/O、网络或渲染
  • 异常前后是否有系统服务报错
  • 是否只有单个 App 异常,还是多个 App 同时异常

如果多个 App 同时出现卡顿、无响应或启动失败,通常就不应该只盯着某一个 App。

三、Framework 层:App 调系统能力的入口

App 不会直接操作大多数硬件和系统资源。

比如 App 想要:

  • 启动 Activity
  • 申请权限
  • 打开相机
  • 播放音频
  • 获取定位
  • 操作蓝牙
  • 访问剪贴板
  • 获取窗口焦点
  • 注册广播
  • 使用传感器

它通常会先调用 Android Framework 提供的 API。

Framework 层可以理解成 App 和系统服务之间的一层 Java 世界。它把底层复杂能力包装成开发者能调用的接口,同时也负责参数检查、权限校验、生命周期管理和跨进程通信封装。

以启动页面为例,简化链路大致是:

1
2
3
4
5
6
7
8
9
10
11
12
App
|
| startActivity()
v
Activity Framework API
|
| Binder
v
ActivityTaskManagerService / ActivityManagerService
|
v
进程启动、Activity 生命周期调度、窗口绘制协作

从稳定性测试角度看,Framework 层的价值在于:

  • 它是很多系统能力的统一入口
  • 它会留下大量可分析日志
  • 它和 system_server 里的系统服务高度相关
  • 它能帮助判断问题是 App 调用错误,还是系统服务处理异常

比如 App 报权限异常,可能要看:

  • App 是否真的声明了权限
  • 运行时权限是否授权
  • PackageManager 状态是否正常
  • AppOps 是否拦截
  • 设备策略或系统配置是否限制

常用观察命令:

1
2
3
4
5
adb shell dumpsys package <package>
adb shell dumpsys activity
adb shell dumpsys window
adb shell dumpsys appops <package>
adb shell dumpsys permission

测试判断重点:

  • App 调用的系统能力是哪一类
  • Framework 是否有明确异常日志
  • 权限、状态、生命周期是否符合预期
  • 是否涉及跨进程 Binder 调用
  • 是否进一步进入 system_server 的系统服务

很多 Android 问题表面看是“某个功能打不开”,实际上是 Framework 调系统服务时失败了。

四、System Server:系统稳定性的核心现场

system_server 是 Android 稳定性测试里必须重点关注的进程。

它里面运行着大量核心系统服务,例如:

  • ActivityManagerService
  • ActivityTaskManagerService
  • WindowManagerService
  • PackageManagerService
  • PowerManagerService
  • InputManagerService
  • DisplayManagerService
  • AlarmManagerService
  • BatteryService
  • ConnectivityService

这些服务直接影响应用启动、窗口显示、输入事件、电源状态、包管理、网络状态、后台调度等关键能力。

所以很多严重稳定性问题,最后都会和 system_server 有关系。

比如:

  • App 启动很慢
  • 页面切换卡住
  • 输入无响应
  • 锁屏解锁异常
  • 黑屏
  • 系统弹窗不出现
  • 全局卡死
  • Watchdog 重启

这些问题都可能需要看 system_server

一条典型调用链可能是:

1
2
3
4
5
6
7
8
9
App 调用 Framework API
|
| Binder IPC
v
system_server 中的系统服务
|
| 调用其他系统服务或 Native 组件
v
返回结果给 App

这里最关键的是 Binder。

App 和系统服务通常不在同一个进程里,跨进程通信主要依赖 Binder。如果 Binder 调用长时间不返回,App 主线程可能会卡住;如果 system_server 某个关键线程被锁住,可能影响一大片系统功能。

稳定性测试里看到 ANR 时,不能只看 App 主线程最后停在哪一行,还要判断它是不是在等系统服务。

例如 traces 里如果看到类似方向:

1
2
main thread
waiting for Binder reply

就要继续追:

  • 它在等哪个系统服务
  • system_server 对应线程在做什么
  • 是否有锁等待
  • 是否有 CPU 饥饿
  • 是否有 I/O 阻塞
  • 是否出现 Watchdog 相关日志

常用观察命令:

1
2
3
4
5
6
7
8
adb shell ps -A | grep system_server
adb shell dumpsys activity
adb shell dumpsys window
adb shell dumpsys input
adb shell dumpsys power
adb shell dumpsys display
adb shell dumpsys SurfaceFlinger
adb bugreport ./bugreport.zip

测试判断重点:

  • system_server 是否发生 crash
  • 是否出现 Watchdog
  • 是否有大量 Binder 阻塞
  • Window、Input、Power、Display 状态是否异常
  • 问题是否影响多个 App 或整个系统
  • 是否伴随系统重启或卡死

如果一个问题影响范围从单 App 扩大到系统级能力,system_server 通常是必须排查的一站。

五、Native Service:很多系统能力真正干活的地方

Android 不是只有 Java Framework 和 system_server。

很多核心能力实际由 Native Service 承担,例如:

  • surfaceflinger:合成和显示相关
  • audioserver / AudioFlinger:音频相关
  • cameraserver:相机相关
  • mediaextractormediacodecmediaserver:媒体相关
  • netd:网络管理相关
  • vold:存储卷管理相关
  • servicemanager:Binder 服务管理
  • hwservicemanager:HAL 服务管理

这些 Native 组件一旦异常,表现可能非常“上层”:

  • 相机打不开
  • 视频播放黑屏
  • 音频无声
  • 系统界面卡顿
  • 屏幕不刷新
  • 网络状态异常
  • 外部存储不可用

但根因并不一定在 App,也不一定在 Java Framework。

以显示链路为例,简化后大致是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
App 绘制界面
|
v
View / RenderThread
|
v
BufferQueue
|
v
SurfaceFlinger
|
v
Display HAL / Kernel Driver
|
v
屏幕显示

如果用户看到黑屏或画面不刷新,可能要看:

  • App 是否还在绘制
  • Window 是否可见
  • Surface 是否创建成功
  • SurfaceFlinger 是否正常合成
  • Display 状态是否正常
  • 底层显示驱动是否异常

常用观察命令:

1
2
3
4
5
6
adb shell ps -A | grep -E "surfaceflinger|audioserver|cameraserver|media|netd|vold"
adb shell dumpsys SurfaceFlinger
adb shell dumpsys media.camera
adb shell dumpsys audio
adb shell dumpsys connectivity
adb logcat -b all -v threadtime

测试判断重点:

  • Native Service 是否 crash 或频繁重启
  • 是否出现 tombstone
  • 是否出现 service died、binder died、transaction failed
  • 是否只有某个硬件相关功能异常
  • 是否需要继续追到 HAL 或 Kernel

Native Service 是系统稳定性测试里很容易被忽略的一层。很多黑屏、音视频、相机、网络、存储问题,如果只看 App 日志,会完全看不到关键现场。

六、HAL 层:系统和硬件之间的抽象边界

HAL 是 Hardware Abstraction Layer,也就是硬件抽象层。

它的价值是让 Android Framework 和系统服务不需要直接理解每一种硬件驱动细节,而是通过统一接口访问硬件能力。

常见 HAL 包括:

  • Camera HAL
  • Audio HAL
  • Sensors HAL
  • Bluetooth HAL
  • GPS / GNSS HAL
  • Wi-Fi 相关 HAL
  • Graphics / Composer HAL
  • Power HAL

从稳定性测试角度看,HAL 层问题通常有几个特点:

  • 现象很像 App 或 Framework 问题
  • 复现往往和具体硬件、版本、场景有关
  • 日志可能分散在 logcat、kernel log、vendor log 中
  • 测试同学通常不能直接修改,但要能判断方向

比如相机黑屏,可能链路是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Camera App
|
v
Camera Framework
|
v
CameraService
|
v
Camera Provider / Camera HAL
|
v
Camera Driver
|
v
Camera Sensor

如果 CameraService 日志显示调用 HAL 超时,或者 provider 进程异常退出,就不能简单归因给 App。

同理,音频、蓝牙、定位、传感器这类问题也经常需要判断是否进入 HAL 层。

常用观察方向:

1
2
3
4
5
6
adb shell lshal
adb shell dumpsys media.camera
adb shell dumpsys audio
adb shell dumpsys sensorservice
adb shell dumpsys location
adb logcat -b all -v threadtime

测试判断重点:

  • 是否只有特定硬件能力异常
  • 是否涉及 vendor 进程或 HAL service
  • 是否有调用超时、返回错误码、服务死亡
  • 是否和特定设备、硬件批次、系统版本相关
  • 是否需要提供更完整的 bugreport、tombstone、kernel log 给底层开发

测试不一定要能深入 HAL 源码,但至少要能识别:

这个问题已经不是普通 App 层问题,需要拉系统或驱动侧一起看。

七、Kernel / Driver 层:系统卡死、重启和资源问题的底座

Kernel / Driver 层是 Android 系统运行的底座。

它负责:

  • 进程和线程调度
  • 内存管理
  • 文件系统
  • 网络协议栈
  • Binder 驱动
  • 电源管理
  • 设备驱动
  • 安全机制

很多严重稳定性问题,最后都要看这一层。

典型现象包括:

  • Kernel Panic
  • 随机重启
  • 设备完全无响应
  • 系统级卡死
  • I/O 长时间阻塞
  • 内存耗尽导致 LMK / OOM
  • 驱动异常导致某个硬件不可用
  • 温升降频导致整体响应变慢

比如设备突然重启,不能只看重启后的 logcat。因为重启后,很多现场已经丢了。需要优先确认:

  • reboot reason 是什么
  • pstore / console-ramoops 是否存在
  • last_kmsg 是否保留
  • 是否有 kernel panic
  • 是否 Watchdog 触发
  • 是否电源、温度或硬件异常

常用观察命令:

1
2
3
4
5
6
7
adb shell cat /proc/meminfo
adb shell cat /proc/uptime
adb shell dmesg
adb shell ls /sys/fs/pstore
adb shell cat /sys/fs/pstore/console-ramoops*
adb shell getprop ro.boot.bootreason
adb shell getprop sys.boot.reason

不同设备权限不一样,有些命令在 user 版本上可能无法直接执行,这时就更依赖 bugreport、厂商日志工具或测试版本权限。

测试判断重点:

  • 是否发生重启、panic、Watchdog 或低内存杀进程
  • 是否有 pstore / last_kmsg 证据
  • 是否有明显驱动报错
  • 是否和高负载、温升、I/O、弱网、频繁插拔相关
  • 是否只有特定硬件版本或批次复现

Kernel 层问题通常不是测试同学独立闭环,但测试需要把证据收集完整。否则底层开发拿不到现场,只能要求复现。

八、用一个“打开相机黑屏”的例子串起来

为了让这条链路更具体,可以用“打开相机黑屏”做例子。

用户现象:

  • 点击相机图标后进入相机页面
  • 页面黑屏
  • 没有预览画面
  • 返回桌面后再打开偶现恢复

如果只从 App 层看,可能会记录为:

1
相机 App 打开后黑屏

但从系统链路看,至少要拆成几层:

1. App 层

先确认:

  • 相机 App 是否 crash
  • 页面 Activity 是否正常启动
  • 是否有权限异常
  • 是否有预览初始化失败日志
  • App 是否阻塞在主线程

常看:

1
2
3
adb logcat -b all -v threadtime
adb shell dumpsys activity top
adb shell dumpsys package <camera_package>

2. Framework / System Server 层

继续确认:

  • Activity 是否处于 resumed
  • Window 是否可见
  • 屏幕是否处于 on 状态
  • 是否有系统权限或 AppOps 拦截
  • 是否存在系统服务超时

常看:

1
2
3
4
adb shell dumpsys activity
adb shell dumpsys window
adb shell dumpsys power
adb shell dumpsys appops <camera_package>

3. Native Service 层

再确认:

  • CameraService 是否正常
  • SurfaceFlinger 是否有对应 layer
  • 是否有 native crash 或 tombstone
  • 是否出现 service died

常看:

1
2
3
adb shell dumpsys media.camera
adb shell dumpsys SurfaceFlinger
adb shell ls /data/tombstones

4. HAL / Driver 层

最后确认:

  • Camera HAL 是否返回错误
  • provider 是否异常
  • kernel log 是否有 camera driver 报错
  • 是否只在某一批设备上复现

常看:

1
2
3
adb shell lshal
adb shell dmesg
adb bugreport ./bugreport.zip

这样分析后,提单就不只是“相机黑屏”,而可以变成:

1
2
3
4
现象:相机应用打开后黑屏,Activity 已 resumed,Window 可见,App 无 Java Crash。
证据:dumpsys media.camera 显示 camera provider 调用异常;logcat 中出现 HAL 返回错误;SurfaceFlinger 中预览 layer 未正常更新。
初步方向:疑似 Camera HAL / provider 异常,需要相机框架和底层侧联合分析。
附件:logcat、bugreport、dumpsys media.camera、SurfaceFlinger dump、复现视频。

这种描述对研发的价值,明显高于一句“相机黑屏,请分析”。

九、稳定性测试里更实用的分层判断法

实际排障时,不需要每次都从 App 一层层查到 Kernel。更实用的方法是根据现象先判断影响范围。

1. 只影响单个 App

优先看:

  • App log
  • Java Crash
  • Native Crash
  • ANR traces
  • App 权限
  • App 资源使用

但要留意系统服务是否有伴随异常。

2. 影响多个 App

优先看:

  • system_server
  • Activity / Window / Input / Power 状态
  • Binder 阻塞
  • CPU / 内存 / I/O 压力
  • bugreport

多个 App 同时异常,通常不适合只从单个 App 归因。

3. 影响某一类硬件能力

比如只有相机、音频、蓝牙、定位、传感器异常。

优先看:

  • 对应系统服务
  • 对应 Native Service
  • HAL service
  • vendor log
  • kernel log

这类问题经常需要系统侧或驱动侧介入。

4. 整机卡死、黑屏、重启

优先看:

  • bugreport
  • pstore / last_kmsg
  • Watchdog
  • Kernel Panic
  • Power / Display / SurfaceFlinger
  • 温度、电量、重启原因

这类问题要优先保现场,不要只重启设备继续跑。

十、不同层常见日志和命令入口

可以先记一张简表。

层级 常见对象 常用证据
App 业务进程、主线程、三方 SDK logcat、ANR traces、meminfo、截图录屏
Framework Android API、权限、生命周期 dumpsys package、activity、appops、permission
System Server AMS、WMS、PMS、Power、Input、Display bugreport、dumpsys activity/window/power/input/display
Native Service SurfaceFlinger、CameraService、AudioFlinger、netd、vold logcat、tombstone、dumpsys SurfaceFlinger/media.camera/audio
HAL camera、audio、sensors、bluetooth、gnss、composer lshal、vendor log、service log、bugreport
Kernel / Driver 调度、内存、文件系统、Binder、设备驱动 dmesg、pstore、last_kmsg、vmcore、reboot reason

这张表不是为了替代分析,而是帮助测试在第一时间知道:

我现在应该先抓哪些证据。

十一、常见误判

理解 Android 分层时,最常见的误判有四类。

第一,把问题出现的位置当成根因位置。比如黑屏出现在相机 App 页面,不代表根因一定在相机 App;也可能是 CameraService、Camera HAL、SurfaceFlinger 或显示驱动异常。

第二,把 App Crash 和系统稳定性完全切开。单个 App Crash 看起来是应用问题,但如果多个 App 都在同一时间出现 Binder timeout、资源申请失败或系统服务异常,就要继续看 system_server 和底层资源状态。

第三,只看 Java 世界,忽略 Native Service 和 HAL。音频、相机、显示、媒体、蓝牙、定位这类问题,经常需要把 logcat、tombstone、dumpsys、vendor log、kernel log 放在一起看。

第四,重启后继续跑测试但不保现场。重启、卡死、Watchdog、Kernel Panic 这类问题的关键证据可能在 pstore、last_kmsg、dropbox 或 bugreport 里,错过第一次现场,后面即使复现路径相同,也不一定还能拿到同样的证据。

所以分层不是为了把问题复杂化,而是为了减少错误归因。

十二、这篇文章真正要建立的能力

Android 系统架构很复杂,但测试开发不需要一开始就把每个模块源码都读完。对稳定性测试来说,更重要的是先建立三种能力。

1. 能把现象放回系统层级里

看到 Crash、ANR、黑屏、卡死、重启时,不只说现象,而是先判断:

  • 单 App 问题
  • Framework / system_server 问题
  • Native Service 问题
  • HAL / Driver 问题
  • Kernel 层问题

判断不一定一次准确,但要有方向。

2. 能按层收集证据

不同层的问题需要不同证据。

只给一个截图,无法分析系统服务异常。只给一段 App log,也无法分析 kernel panic。测试要能根据问题类型补齐:

  • logcat
  • bugreport
  • dumpsys
  • tombstone
  • traces
  • pstore
  • Perfetto / systrace
  • 复现视频

3. 能输出初步归因,而不是只转发日志

好的稳定性问题单不一定要求测试直接给最终根因,但至少要能说明:

  • 影响范围
  • 发生时间
  • 复现路径
  • 关键证据
  • 初步怀疑层级
  • 建议责任方向
  • 还缺哪些日志

这就是系统稳定性测试和普通功能测试最大的区别之一。

十三、小结

Android 从 App 到 Kernel 的调用链,可以先按六层理解:

  1. App 层负责业务逻辑和用户交互。
  2. Framework 层提供系统 API 和调用封装。
  3. System Server 承载大量核心系统服务,是系统稳定性的关键现场。
  4. Native Service 承担显示、音频、相机、媒体、网络、存储等底层系统能力。
  5. HAL 层连接系统服务和硬件能力。
  6. Kernel / Driver 层负责调度、内存、I/O、网络、电源、驱动和硬件交互。

做稳定性测试时,不能只看问题发生在哪个界面,而要继续追问:

这个现象背后的调用链走到了哪一层,哪一层最可能先出问题,哪一层还缺证据。

只要这个意识建立起来,后面再学 logcatbugreporttombstoneANR tracesdumpsyspstorePerfetto,就不会变成零散命令,而会变成一套有方向的问题定位方法。