Skip to main content

Chapter 197: Mobile Architecture Extension Paths

读完本书以后,继续深入移动系统架构的核心动作是把一个 App 可见现象拆成若干延伸路径,再判断每条路径应该追到哪一层、使用哪类资料、用什么证据停止追踪。本章讨论的主问题是:如何从已经建立的“能力路径 + 横切策略 + 平台边界”心智模型,走向内核、图形、媒体、安全、运行时和工具链等长期平台工程能力。

本章使用一个贯穿场景:视频社交 App 打开录制页后,请求相机和麦克风权限,启动预览,叠加美颜和字幕,录制一段视频,随后编码、保存、上传;用户看到的异常可能是权限拒绝、预览黑屏、首帧慢、掉帧、发热、音画不同步、上传失败或崩溃。这个场景覆盖 App、Framework、系统服务、运行时、内核、驱动、硬件和策略控制面,适合作为后续学习路径的分叉入口。

延伸学习的稳定顺序是先固定现象,再固定责任链,然后选择深挖路径。权限拒绝优先走安全路径,首帧慢和卡顿优先走运行时或图形路径,编码失败优先走媒体路径,持续发热优先走电源、调度和硬件路径,崩溃和无响应优先走工具链路径。多个症状同时出现时,先用时间线对齐,再判断主导瓶颈。

本章的最终结论是:后续学习不应按名词收藏资料,而应按可追踪的系统问题组织。每条路径都要保留同一组问题:App 触发了什么,Framework 暴露了什么入口,系统服务持有什么状态,策略在哪个边界执行,资源如何调度,失败如何返回给用户。这样继续阅读 Android 公开源码、Android 官方文档、Apple 公开文档、Darwin / XNU 公开材料和工具输出时,材料会进入同一个架构框架。

下面这张图把贯穿场景拆成后续延伸学习的入口。图中的每条分支都可以独立深入,但它们共享同一条上游请求链。

图中的关键点是“异常先进入现象,再进入路径”。同一个发热现象可能来自相机 ISP、GPU shader、视频编码、蜂窝上传或后台重试;同一个掉帧现象可能来自 UI 主线程、RenderThread、Surface 队列、GPU command、系统合成或显示刷新。后续训练的目标是把可见现象还原成责任链,而非把所有资料平均阅读。

197.1 Kernel Path:调度、内存、驱动、电源、安全

Kernel Path 解决的问题是:当 App 可见现象已经超出单个 Framework API 的解释范围时,如何继续追踪 CPU 调度、内存压力、设备访问、电源状态和安全边界。内核在移动系统中承担资源所有权:它调度线程,分配和回收内存,管理文件和网络 I/O,承接 driver 对硬件的访问,执行一部分权限和隔离策略,并把电源状态、wakeup source、thermal pressure 等信号传给上层策略。

在贯穿场景中,录制页发热并掉帧时,Kernel Path 的起点并非源码目录,而是资源事实。先看 CPU 是否被 UI、渲染、编码、相机回调、上传线程同时占用,再看内存中是否有 camera buffer、graphic buffer、encoder input、文件缓存和 Java / Swift 对象堆同时增长,随后看设备驱动是否在等待 fence、DMA buffer、codec queue 或 camera request。这个顺序把“慢”拆成可定位对象。

Android 的内核延伸路径可以从 Linux 调度、memory management、cgroup、binder driver、dma-buf、power management、SELinux 和 Android Generic Kernel Image 边界展开。Android 官方的 Architecture overview 可以作为系统分层入口,后续再进入 kernel、HAL、Binder、power、graphics 相关材料。阅读本地源码时使用 AOSP_SRC=/path/to/aosp 作为占位路径,先找公开接口和调用边界,再进入实现细节。

Apple 平台的内核延伸路径需要分清公开 Darwin / XNU 组件、开发者文档和平台行为推断。XNU、Mach、BSD layer、I/O Kit 的公开材料能帮助理解线程、虚拟内存、文件、网络和 driver model 的一般边界;iOS 上具体系统 daemon、driver 组合和部分策略实现属于私有平台实现。阅读 Apple 方向时,可以把 DARWIN_SRC=/path/to/darwin-source 当作公开源码占位,把开发者可观测到的行为作为证据,把私有实现留在“合理推断”层级。

Kernel Path 的学习顺序应按责任面推进。调度先回答“哪个线程在什么时候占用 CPU”;内存先回答“哪些对象和 buffer 占用物理内存、触发压缩或回收”;驱动先回答“哪个设备队列或 fence 阻塞资源流”;电源先回答“哪个硬件单元持续活跃、触发温控或频率收缩”;安全先回答“哪个内核或策略边界拒绝访问”。这五个问题能覆盖大部分移动平台故障。

在录制页案例中,预览掉帧可能由相机 HAL 交付不稳定、GPU 合成等待 buffer、编码器占用内存带宽、热策略降低频率共同造成。Kernel Path 的判断方法是先固定时间线,再把每个异常点映射到内核对象:线程调度延迟、binder transaction 等待、dma-buf fence 未 signal、page fault 增多、thermal state 升级。上层日志说明现象,内核证据说明资源状态。

Kernel Path 的边界是版本和设备差异。Android 不同 kernel branch、OEM vendor module、SoC driver 和 power HAL 会改变实际路径;Apple 不同芯片和系统版本也会改变调度与电源策略的可观测结果。因此内核学习应把“通用 OS 原理”和“移动平台定制点”分开放置。通用原理解释资源为何受限,平台定制点解释具体设备为何出现不同表现。

197.2 Graphics Path:GPU、Composition、Display、VSync、Frame Trace

Graphics Path 解决的问题是:当用户看到卡顿、黑屏、撕裂感、首帧慢或动画不连续时,如何追踪一帧从 App 绘制到屏幕扫描输出的路径。图形路径的核心对象是 draw call、render thread、GPU command、surface buffer、system compositor、display engine、VSync 和 frame deadline。

在贯穿场景中,录制页通常同时包含相机预览、滤镜、美颜、字幕、按钮动画和编码预览。App 看起来只是在一个页面里显示视频,系统内部却要完成 camera buffer 交付、GPU 纹理采样、shader 处理、UI layer 合成、buffer 提交、系统合成和显示刷新。任一阶段超过 frame budget,用户都会看到掉帧或输入延迟。

Android 的图形延伸路径可以从 Android Graphics 进入,重点建立 Surface、BufferQueue、SurfaceFlinger、Hardware Composer、fence、VSync 和 display pipeline 的关系。应用层可以从 View / RenderThread / OpenGL ES / Vulkan / MediaCodec surface 入手,系统层继续追踪 SurfaceFlinger 的 layer 合成选择、HWC overlay 使用、GPU composition fallback 和 present fence。

Apple 平台的图形延伸路径应从 Core Animation、Metal、UIKit / SwiftUI 渲染入口、display link、drawable 和 Instruments 的帧分析资料进入。iOS 的系统合成器内部实现公开程度有限,但开发者可以通过 Core Animation 提交、Metal command buffer、drawable 获取和 frame pacing 观察到关键边界。Apple 方向的稳定结论应落在公开 API、工具观测和行为模型上。

Graphics Path 的判断顺序是先拆帧,再拆队列,再拆硬件。拆帧时看主线程、布局、动画提交和渲染线程是否错过目标时间;拆队列时看 surface buffer 是否生产过慢、消费阻塞或 fence 等待;拆硬件时看 GPU、display engine、memory bandwidth 和刷新率策略是否成为瓶颈。这个顺序可以把“页面卡”拆成 App 责任、系统合成责任和硬件能力边界。

录制页案例中,黑屏通常要先区分“没有拿到相机帧”“拿到帧但没有绑定到渲染纹理”“渲染成功但 buffer 没有提交”“系统合成没有显示该 layer”。这四个判断分别落在 camera pipeline、GPU 渲染、surface buffer 和 compositor 层。若把它们混成“相机黑屏”,排查会在 Camera、OpenGL / Metal、UI 生命周期之间来回跳转。

Frame Trace 是 Graphics Path 的核心训练材料。Android 可用 Perfetto、SurfaceFlinger 相关 trace、FrameTimeline、GPU counter 和 systrace 历史资料建立时间线;Apple 可用 Instruments 的 Time Profiler、Core Animation、Metal System Trace 等工具方向建立时间线。工具名称会随系统和 Xcode 版本变化,稳定方法是查看一帧的生产者、消费者、等待点和显示提交点。

Graphics Path 最终训练的是“帧责任边界”。App 负责准备内容和提交 buffer,系统合成器负责组织 layer、同步 fence 和选择合成方式,显示硬件负责按刷新时序扫描输出。功耗和温控会改变这条路径,例如降低刷新率、降低 GPU 频率、调整亮度或减少后台渲染机会。图形问题最终要同时解释流畅度和资源预算。

197.3 Media Path:Codec、Container、Camera、Audio、Pipeline

Media Path 解决的问题是:当录制、播放、编码、解码、音画同步或文件封装出现异常时,如何把媒体问题拆成采集、处理、编码、封装、存储和播放的责任链。媒体系统的核心对象是 stream、buffer、timestamp、codec session、container、audio route、camera metadata 和 pipeline backpressure。

贯穿场景中的录制页同时使用 camera、microphone、GPU filter、video encoder、audio encoder、muxer、file writer 和 uploader。用户看到“录出来的视频卡”时,问题可能发生在预览帧率、编码输入、codec 输出、音频采样、时间戳对齐、文件写入或上传转码。Media Path 的第一步是把“录制”拆成多条流,而非把它当作一个按钮动作。

Android 的媒体延伸路径可以从 Android Media、Camera2 / CameraX、MediaCodec、MediaMuxer、AudioRecord、AudioTrack、AAudio、AudioFlinger 和 camera HAL 相关公开材料进入。应用 API 说明入口,framework 和 native service 说明资源所有权,HAL 和 driver 说明硬件能力边界,codec capability 和 stream configuration 说明设备差异。

Apple 平台的媒体延伸路径可以从 AVFoundation、Core Media、VideoToolbox、AudioToolbox、Core Audio 和 Metal / Core Image 相关公开文档进入。AVCaptureSession 表示采集图,CMSampleBuffer 表示带时间戳的媒体样本,VideoToolbox 承接硬件编解码,AVAssetWriter / AVAssetReader 承接文件写入和读取。具体硬件调度由系统封装,公开 API 和工具输出是主要证据。

Media Path 的判断顺序是先看流格式,再看时间戳,再看 buffer,再看硬件能力。流格式包括分辨率、像素格式、采样率、声道数、码率、GOP、HDR profile 和色彩空间;时间戳决定音画同步;buffer 决定背压和内存占用;硬件能力决定某组 stream combination 是否稳定。这个顺序能把“编码失败”拆成输入不兼容、队列阻塞、硬件能力不足或容器写入失败。

录制页案例中,音画不同步通常来自时间线断裂。视频帧可能经历 camera sensor timestamp、ISP 输出、GPU filter、encoder input、encoder output、muxer 写入;音频样本可能经历 microphone、audio HAL、AudioRecord callback、audio encoder、muxer 写入。两条流进入同一个 container 时,muxer 需要以 timestamp 对齐写入。只看 UI 预览无法判断文件内部时间戳是否稳定。

Media Path 还必须处理功耗和热边界。高分辨率预览、实时美颜、HDR、视频编码和蜂窝上传会同时占用 ISP、GPU、NPU、codec、DRAM、flash 和 modem。系统可能降低帧率、关闭高阶效果、调整码率或终止后台任务。媒体问题因此经常同时具备性能症状和策略症状,排查时要把“能力支持”和“当前状态允许”分开判断。

Media Path 的学习目标是形成 pipeline 设计能力。一个稳定媒体 pipeline 要明确每段输入输出格式、队列深度、时间戳来源、线程归属、硬件能力查询、错误传播和降级策略。对 Android 和 Apple 都适用的结论是:媒体 API 表面越简单,内部责任链越需要被显式建模;否则问题会在相机、音频、编解码、文件和 UI 之间互相遮蔽。

197.4 Security Path:Sandbox、Permission、Signature、TEE、Exploit Mitigation

Security Path 解决的问题是:当能力访问、数据访问、进程隔离、代码加载、设备完整性或敏感硬件调用受到限制时,如何定位安全边界和策略执行点。移动平台安全由多个层级叠加:应用身份、签名、权限、sandbox、IPC 调用者身份、系统服务检查、内核访问控制、硬件密钥和漏洞缓解共同决定一次操作是否被接受。

贯穿场景中的录制页最先碰到 camera、microphone、photos 或 storage 相关授权。用户点击“允许”只是安全路径的一段输入。系统还会检查 App identity、runtime permission、foreground state、AppOps 或等价策略、media projection / privacy indicator、后台访问限制、文件容器边界和跨进程调用者身份。权限弹窗解决授权表达,系统服务解决实际执行。

Android 的 Security Path 可以从 runtime permission、AppOps、package signature、UID sandbox、SELinux、Binder caller identity、Verified Boot、Keystore / StrongBox 和 TEE / Trusty 方向展开。Android 官方 Verified Boot 适合理解启动完整性和系统分区信任,权限与 SELinux 相关材料适合理解运行期访问控制,Keystore 相关材料适合理解密钥使用边界。

Apple 平台的 Security Path 应从 code signing、entitlements、App Sandbox、Data Protection、Keychain、Secure Enclave、privacy permission 和 Apple Platform Security 公开材料展开。Apple 的 Platform Security 可以作为硬件安全、启动安全、数据保护和系统安全的公开入口。iOS 的大量策略实现属于闭源系统组件,正文结论应基于公开文档、开发者 API 行为和可观测限制。

Security Path 的判断顺序是先看身份,再看授权,再看执行点,再看数据边界。身份回答“谁在请求”;授权回答“用户、开发者或平台是否授予能力”;执行点回答“哪个服务、内核策略或硬件单元做出接受或拒绝”;数据边界回答“结果能流向哪里”。这个顺序能区分“权限没给”“权限给了但状态不满足”“服务拒绝”“底层策略拒绝”和“结果被容器边界收束”。

录制页案例中,相机权限已授予但后台录制失败,安全路径要看前台状态、privacy indicator、camera service 资源所有权、后台策略和平台版本。Android 与 Apple 都会把敏感硬件访问和用户可见状态绑定,但具体 API、提示形式、后台限制和错误码不同。跨平台比较时使用同一组维度:入口 API、权限记录、前后台状态、服务检查、用户可见提示、失败返回。

TEE 和 Secure Enclave 相关学习要把硬件安全放回能力路径。硬件安全单元通常用于密钥保护、生物特征相关数据保护、支付、设备解锁或可信执行。App 通常拿不到硬件内部状态,只能通过 KeyStore、Keychain、LocalAuthentication、Secure Enclave 相关公开 API 使用封装能力。安全芯片的存在说明密钥材料和高敏感操作从主应用处理器中分离出来,具体实现边界以平台公开文档为准。

Exploit Mitigation 的延伸学习也要服务架构判断。ASLR、DEP / W^X、CFI、PAC、SELinux、sandbox profile、hardened runtime、memory tagging 等机制分别作用在内存布局、代码执行、控制流、系统调用、IPC、进程权限和硬件辅助检查上。学习这些机制时,先问它保护哪条边界,再问攻击需要穿过哪些层,再问失败信号会出现在崩溃、权限拒绝、日志还是系统重启中。

197.5 Runtime Path:ART、Zygote、dyld、Swift Runtime、Objective-C Runtime

Runtime Path 解决的问题是:当启动慢、页面首帧慢、内存上涨、GC / ARC 压力、动态库加载、反射、消息分发或崩溃和语言运行时有关时,如何追踪 App 代码进入系统执行环境的过程。运行时位于 App 代码和 OS 服务之间,它决定代码如何加载、对象如何分配、方法如何调用、线程如何创建、异常如何传播。

在贯穿场景中,录制页启动慢可能发生在冷启动、动态库加载、依赖初始化、权限请求回调、相机对象创建、UI 首帧构建、shader / model 预热或编码器初始化。Runtime Path 的作用是把“业务页面慢”拆成进程创建、代码加载、类初始化、对象分配、JIT / AOT、主线程任务和跨线程回调。

Android 的 Runtime Path 可以从 Android runtime and Dalvik、ART、Zygote、dex / oat、class loading、JNI、GC、Binder callback 和 baseline profile 方向展开。Zygote 提供进程孵化模型,ART 管理字节码执行、编译和 GC,JNI 连接 managed code 与 native library。启动和卡顿分析要同时看 Java / Kotlin 层、native 层和 Binder 回调线程。

Apple 平台的 Runtime Path 可以从 dyld、Mach-O、Swift Runtime、Objective-C Runtime、ARC、dispatch queues、RunLoop、UIKit / SwiftUI 生命周期和 crash report 符号化方向展开。dyld 负责镜像加载和符号绑定,Swift / Objective-C runtime 负责类型、metadata、动态派发、对象生命周期和异常相关边界。公开文档和 crash report 能说明开发者可见层,系统私有 framework 的内部初始化需要谨慎标注为推断。

Runtime Path 的判断顺序是先看进程和加载,再看主线程,再看对象生命周期,再看跨边界调用。进程和加载解释冷启动;主线程解释首帧和交互延迟;对象生命周期解释内存增长和 GC / ARC 压力;跨边界调用解释 JNI、Binder、XPC、callback、delegate 和 async task 的等待关系。这个顺序能把“启动慢”拆成多个可验证阶段。

录制页案例中,美颜 SDK 初始化可能在主线程加载 native library、读取模型文件、创建 GPU context、注册相机回调和申请权限结果回调。Android 上要看 Zygote fork 后的 class loading、JNI library load、ART compilation state 和 Binder service 获取;Apple 上要看 dyld load、Swift static initialization、Objective-C +load / initialize 行为、main run loop 和 AVFoundation session start。两边共同问题是初始化任务是否阻塞首帧。

Runtime Path 和内存路径经常交叉。相机和图形 buffer 占用 native memory,Java / Kotlin 对象或 Swift / Objective-C 对象占用 runtime 管理的堆,codec 和 GPU 资源又可能在 driver 或 system service 侧占用内存。App 看到的“内存高”需要拆成 managed heap、native heap、mapped file、graphic buffer、media buffer 和系统代持资源。

Runtime Path 的最终训练目标是建立“代码执行环境”心智模型。应用代码并非直接运行在硬件上,它经过进程模型、loader、runtime、threading model、IPC callback 和系统服务返回。继续学习运行时时,不应停留在语言语法和 API 用法,而要追踪对象何时创建、在哪个线程运行、持有什么系统资源、如何释放、失败如何进入 crash 或 ANR / watchdog 体系。

197.6 Tooling Path:Tracing、Profiling、Crash Analysis、Static Analysis

Tooling Path 解决的问题是:当系统路径已经拆开后,如何用工具把猜测变成证据。工具链覆盖 tracing、profiling、crash analysis、static analysis、日志、符号化、heap dump、frame trace、energy report 和网络抓取等方向。工具的价值在于回答具体问题:时间花在哪里,资源由谁持有,等待发生在哪个边界,崩溃栈指向哪段代码,静态依赖是否引入风险。

贯穿场景中的录制页可以提出一组工具问题:首帧慢是否来自主线程初始化;掉帧是否来自 GPU、Surface 队列或系统合成;发热是否来自编码、渲染、相机、modem 或后台重试;崩溃是否来自 native library、权限状态、生命周期回调或资源释放;安装包中是否包含高风险动态加载或过大的模型资源。每个问题对应不同工具入口。

Android 的 Tooling Path 可以按 Perfetto / System Trace、Android Studio Profiler、logcat、tombstone、ANR trace、bugreport、FrameTimeline、GPU profiling、simpleperf、heap dump、lint 和 static analysis 展开。Android 官方文档中 architecture、graphics、runtime、media、security 各自提供入口,但工具输出需要回填到“App → Framework → Service → Kernel / Driver / Hardware”的责任链。

Apple 的 Tooling Path 可以按 Instruments、Xcode Organizer、MetricKit、crash report、spindump、sysdiagnose、Metal tools、Memory Graph、Thread Sanitizer、Address Sanitizer、Static Analyzer 和 App Store Connect 诊断资料展开。Instruments 适合建立时间线,crash report 适合定位崩溃栈,MetricKit 适合观察线上性能与稳定性指标。系统私有进程的细节通常只能作为背景线索。

Tooling Path 的判断顺序是先选问题,再选时间范围,再选指标,再解释责任。问题要具体,例如“点击录制按钮后 2 秒内首帧为何没有出现”;时间范围要能覆盖用户动作和系统返回;指标要和路径对应,例如主线程任务、GPU command、codec queue、thermal state、网络请求、crash stack;责任解释要回到 App、Framework、系统服务、内核、驱动或硬件。

录制页案例中,如果用户反馈“录制 20 秒后开始卡”,一次有效 trace 要覆盖录制前准备、开始录制、稳定录制、卡顿出现、停止录制五段。若只截取卡顿瞬间,可能看不到前面 buffer 堆积、温控升级、编码器背压或上传重试。Tracing 的核心是时间线完整性,Profiling 的核心是热点归属,Crash Analysis 的核心是栈和生命周期状态,Static Analysis 的核心是结构性风险。

Crash Analysis 要和 Runtime Path、安全路径一起使用。Java / Kotlin exception、native crash、watchdog、ANR、OOM、Swift fatal error、Objective-C exception、EXC_BAD_ACCESS、jetsam 等信号分别指向不同责任层。崩溃栈只是入口,还要结合线程状态、最近用户动作、权限状态、资源释放顺序和版本差异,才能判断是 App 代码错误、平台 API 使用边界、系统资源压力还是设备特定问题。

Static Analysis 的作用是提前发现风险边界。权限声明、动态库加载、反射、JNI、后台任务、文件访问、隐私 API、网络安全配置、符号可见性、Swift / Objective-C 混编、第三方 SDK 依赖和 native memory 管理都可以被静态检查部分覆盖。静态结论需要运行期证据补足,因为移动平台策略常常依赖前后台状态、电量、温度、权限记录和设备能力。

197.7 Android Source Reading Path 与 Apple Documentation Reading Path

Android Source Reading Path 与 Apple Documentation Reading Path 解决的问题是:面对两套公开程度差异很大的平台资料,如何保持同一套阅读方法。Android 提供 AOSP、官方架构文档、Android Code Search 和大量公开接口;Apple 提供开发者文档、Platform Security、Darwin / XNU 公开源码、WWDC 材料、工具输出和 crash report。资料形态不同,阅读目标应保持一致:定位入口、责任主体、策略检查、资源边界和失败返回。

Android 源码阅读适合按能力路径进入。以录制页为例,Camera2 API 可以引出 framework manager、camera service、provider / HAL、buffer、permission、AppOps 和 native service;MediaCodec 可以引出 codec service、surface input、buffer queue 和 hardware codec;Surface 可以引出 SurfaceFlinger、HWC、fence 和 display。每次阅读只围绕一个请求,不把源码树按目录平均展开。

阅读 Android 源码时,先看公开 API 和文档,再看 interface,再看 service,再看 native / HAL,再看 kernel 交互点。AIDL / HIDL / stable AIDL、Binder transaction、service manager、system_server、native daemon、vendor boundary 是常见分界线。遇到 OEM 差异时,把 AOSP 作为共同模型,把 vendor 实现作为设备变量,把日志或 trace 作为实际设备证据。

Apple 资料阅读适合按公开契约进入。以录制页为例,AVCaptureSession、AVAudioSession、AVAssetWriter、Core Animation、Metal、LocalAuthentication、Keychain、MetricKit 和 Instruments 是开发者可见入口。XNU / Darwin 公开源码能解释内核通用机制,Platform Security 能解释公开安全模型,具体 iOS 系统服务和硬件策略需要通过公开文档、API 行为和工具观测形成边界判断。

Apple 方向的阅读方法应把“可知层级”写清楚。公开 API 行为可以直接作为工程依据;公开文档中的安全和隐私模型可以作为平台策略依据;Darwin / XNU 公开源码可以作为内核机制参考;私有 daemon、私有 framework 和硬件调度细节只能作为基于行为的推断。这样能保留架构判断,又不会把不可验证细节写成已知实现。

Android 与 Apple 的长期对齐方法是使用同一张责任链表。入口 API 对齐入口,系统服务 / daemon 对齐资源所有者,permission / entitlement 对齐授权边界,kernel / driver framework 对齐硬件访问,tooling 对齐可观测证据,用户可见错误对齐返回结果。平台差异会改变名称和实现,但不会改变移动 OS 需要仲裁硬件、保护隐私、控制功耗和维持体验的共同问题。

在贯穿场景中,Android 方向可以把相机黑屏追到 camera service、HAL stream configuration、Surface、BufferQueue 和权限状态;Apple 方向可以把同类问题追到 AVCaptureSession 配置、authorization status、session interruption、preview layer、AVAudioSession route 和 runtime error notification。两边都要回答:App 请求是否成立,系统是否授予资源,硬件路径是否可用,失败是否被回调或日志表达。

源码和文档阅读的终点是形成可迁移判断,而非记住某个版本的函数名。函数名、类名、daemon 名、工具 UI 会变;稳定的是路径问题:谁拥有资源,谁检查策略,谁排队,谁返回错误,谁把状态显示给用户。后续每次阅读新材料,都应把它放入这五个问题中。

197.8 从手机系统架构走向平台工程能力

从手机系统架构走向平台工程能力,核心变化是从“理解系统如何分层”进入“对一个平台问题给出可执行判断”。平台工程能力要求把现象、责任、证据和取舍放在同一张图中:现象来自用户或 App,责任分布在多层系统,证据来自文档、源码、trace、profile、crash 和行为复现,取舍发生在安全、功耗、性能、兼容性和体验之间。

贯穿场景中的录制页可以作为最终训练模板。权限失败要进入 Security Path,首帧慢要进入 Runtime Path,预览掉帧要进入 Graphics Path,音画不同步要进入 Media Path,持续发热要进入 Kernel / Power Path,线上崩溃要进入 Tooling Path。平台工程师的任务是先建立主导路径,再处理交叉路径。主导路径决定第一批证据,交叉路径解释复合症状。

平台工程判断需要一套固定输出格式。第一句说明用户可见现象;第二步画出 App 到系统服务的请求路径;第三步列出策略检查点和资源边界;第四步标出证据来源;第五步给出可能根因排序;第六步给出降级或修复方案;第七步写出版本和设备边界。这个格式让讨论从主观感受转向可验证路径。

移动平台的工程取舍通常发生在横切控制面上。安全要求收紧能力入口,隐私要求用户可见和可撤销,电源要求限制后台和持续硬件访问,温控要求降低频率或质量,兼容性要求保留旧 API 行为,体验要求前台响应稳定。一次录制功能看似是产品能力,系统实现上却是多个控制面共同放行后的结果。

继续学习时,可以把所有资料分成三类。第一类是结构资料,回答系统如何分层,例如 Android architecture、Apple Platform Security、Darwin / XNU 源码和平台框架文档;第二类是路径资料,回答一次请求如何流动,例如 camera、media、graphics、runtime 和 permission 文档;第三类是证据资料,回答当前设备当前版本发生了什么,例如 trace、profile、crash、日志和指标。三类资料要组合使用。

平台工程能力还要求承认信息边界。Android AOSP 能提供共同架构,但真实设备包含 SoC vendor、OEM service、GMS、carrier policy 和系统版本差异;Apple 公开资料能提供开发者契约、安全模型和部分内核机制,但 iOS 私有系统组件和硬件调度细节开放有限。可靠结论要标注证据来源和推断层级。

本书最后留下的迁移方法是:任何移动系统问题都先写成一条能力路径,再叠加横切策略。能力路径回答“请求如何到达资源”,横切策略回答“请求为何被接受、延迟、降级或拒绝”。当读者继续进入内核、图形、媒体、安全、运行时和工具链时,这个模型能保持阅读方向,不会被平台名词、工具界面或源码规模淹没。

最小自检任务

题目:一个视频 App 在 Android 和 iOS 上都实现了“打开录制页 → 请求相机和麦克风 → 显示预览 → 录制 30 秒 → 保存并上传”的流程。线上反馈显示:部分设备首帧慢,录制 20 秒后掉帧并发热,少量用户保存失败。请按本章的延伸路径方法,写出主导路径、交叉路径、责任边界、证据来源和用户可见结果。

答案要点

主导路径应先按症状拆分。首帧慢优先进入 Runtime Path 和 Graphics Path,检查进程冷启动、动态库加载、SDK 初始化、主线程任务、预览 surface / preview layer 创建和首个 buffer 提交。录制 20 秒后掉帧并发热优先进入 Graphics Path、Media Path 和 Kernel Path,检查 GPU 渲染、系统合成、camera / codec buffer、编码背压、DRAM 带宽、CPU / GPU / ISP / codec 活跃状态和 thermal state。保存失败优先进入 Media Path 和 Security Path,检查 muxer / writer 状态、文件容器权限、存储空间、后台状态和系统返回错误。

责任边界应按 App、Framework、系统服务、内核 / 驱动、硬件和横切策略书写。App 负责初始化顺序、线程调度、资源释放和错误处理;Framework 暴露 camera、audio、media、graphics、file 和 network API;系统服务持有相机、音频、媒体、窗口、权限和存储状态;内核 / 驱动处理调度、内存、buffer、设备队列和电源信号;硬件包括 sensor、ISP、GPU、codec、DRAM、flash 和 modem;横切策略包括权限、前后台、电源、温控、隐私提示和设备能力。

证据来源应和路径对应。Android 可使用 Perfetto / System Trace、FrameTimeline、logcat、ANR / tombstone、Android Studio Profiler、MediaCodec / Camera 相关错误和 bugreport 方向;iOS 可使用 Instruments、MetricKit、crash report、Memory Graph、Metal / Core Animation 相关工具方向和 AVFoundation runtime error / interruption 回调。证据解释要回到时间线:启动、首帧、稳定录制、卡顿出现、保存、上传。

用户可见结果要写成路径输出。首帧慢表现为预览延迟或黑屏停留;掉帧和发热表现为预览不连续、机身升温、电量下降和可能的质量降级;保存失败表现为文件缺失、导出失败、上传无输入或错误提示。最终判断要包含版本和设备边界:不同 Android API level、OEM vendor 实现、SoC 能力、iOS 版本、机型硬件和系统策略都可能改变具体表现。

本章知识点总结

  • 延伸入口:后续学习应从 App 可见现象进入能力路径,再选择内核、图形、媒体、安全、运行时或工具链方向。
  • 贯穿场景:视频录制页能同时暴露权限、预览、编码、发热、掉帧、保存和上传问题,适合作为移动架构综合训练材料。
  • Kernel Path:内核方向要按调度、内存、驱动、电源和安全五个责任面追踪资源事实。
  • Graphics Path:图形方向要把一帧拆成 App 绘制、buffer 提交、系统合成、fence 同步和显示扫描输出。
  • Media Path:媒体方向要把录制拆成采集、处理、编码、封装、存储和播放,多条流通过 timestamp 和 buffer 形成管线。
  • Security Path:安全方向要按身份、授权、执行点和数据边界定位权限拒绝、沙箱限制、签名约束和硬件安全能力。
  • Runtime Path:运行时方向要追踪进程创建、代码加载、主线程任务、对象生命周期和跨边界回调。
  • Tooling Path:工具方向要先固定问题和时间范围,再选择 trace、profile、crash 或 static analysis 证据。
  • Android 阅读:Android 源码阅读应从公开 API 和接口进入 service、native / HAL、kernel 交互点和 vendor 边界。
  • Apple 阅读:Apple 资料阅读应区分公开 API、公开安全模型、Darwin / XNU 公开源码和基于行为的实现推断。
  • 平台工程:平台工程能力要求把现象、责任、证据、根因排序、修复方案和版本设备边界写成可验证判断。
  • 最终模型:能力路径回答请求如何到达资源,横切策略回答请求为何被接受、延迟、降级或拒绝。