1. Android系统概述:从零到一,理解这个庞大的生态

大家好,我是你们的老朋友。今天咱们正式开篇,聊聊Android系统到底是个什么东西。

说实话,我刚开始接触Android时,也觉得它就是个手机操作系统。但干得越久,越发现它其实是一个庞大的、分层清晰的软件栈。你想想看,从你手指触摸屏幕,到App做出响应,中间经历了多少层?每一层都在干什么?

嗯,这节课我们就来拆解它。

1.1 Android发展史:一个开源项目的逆袭

先简单回顾一下历史。Android最初不是Google做的,而是Andy Rubin创办的Android公司。2005年被Google收购,2007年正式对外发布。

我记得当时市面上还是塞班和Windows Mobile的天下。Android 1.0发布时,说实话,功能很简陋。但它的杀手锏是什么?开源。任何厂商都可以免费使用、修改。

这直接导致了后来三星、HTC、华为等厂商的疯狂涌入。我经历过Android 2.3(Gingerbread)到4.0(Ice Cream Sandwich)的过渡期,那会儿碎片化问题特别严重。但Google后来通过CTS(兼容性测试套件)和GMS(Google移动服务)逐渐规范了生态。

到了Android 5.0(Lollipop),ART运行时替换了Dalvik,性能有了质的飞跃。再往后,Android 10开始引入Project Treble,把系统框架和厂商驱动解耦,升级难的问题才真正得到缓解。

我个人习惯把Android发展史分为三个阶段:

  • 野蛮生长期(1.0-4.4):功能快速迭代,但碎片化严重
  • 成熟稳定期(5.0-9.0):ART、Material Design、权限管理逐步完善
  • 现代架构期(10.0-至今):Treble、动态分区、隐私保护成为核心

小提示:如果你在调试老设备,比如Android 4.4以下的系统,很多现代调试工具(如adb shell dumpsys)可能不支持。我建议你至少准备一台Android 10以上的设备做主力调试机。

1.2 Android系统架构分层:五层结构,各司其职

Android架构从上到下分为五层。我画个简图帮你理解:

+-----------------------------+
|        应用层 (App)          |  ← 你写的APK
+-----------------------------+
|      应用框架层 (Framework)   |  ← ActivityManager, WindowManager等
+-----------------------------+
|       系统服务层 (Services)   |  ← SurfaceFlinger, AudioFlinger等
+-----------------------------+
|    硬件抽象层 (HAL)          |  ← Camera HAL, Audio HAL等
+-----------------------------+
|      Linux内核层 (Kernel)    |  ← 驱动、内存管理、进程调度
+-----------------------------+

每一层都只依赖下一层,不跨层调用。这样做的好处是:解耦。你换一个厂商的硬件,只要HAL层实现对了,上面的Framework和App完全不用改。

我曾经在一个项目中遇到过:某厂商换了摄像头传感器,结果上层拍照App直接闪退。查了半天,发现是HAL层返回的数据格式和Framework预期的不一致。这就是分层没做好的典型问题。

1.2.1 Linux内核层(Kernel)

这是Android的根基。说白了,Android就是跑在Linux内核上的。内核负责什么?

  • 进程调度:决定哪个App先跑
  • 内存管理:分配和回收内存
  • 驱动:屏幕、触摸、Wi-Fi、蓝牙等硬件驱动
  • 安全:基于Linux的权限模型

但Android对Linux内核做了不少改动。比如添加了Binder驱动,这是Android进程间通信(IPC)的核心。还有ashmem(匿名共享内存)、wakelock(唤醒锁)等。

重点:Binder是Android的灵魂。所有跨进程通信,比如App调用系统服务,底层都是通过Binder完成的。调试时,你可以用 adb shell lsof | grep binder 查看哪些进程在使用Binder。

1.2.2 硬件抽象层(HAL)

HAL层是连接内核和Framework的桥梁。为什么需要它?

你想想看,不同厂商的摄像头驱动接口可能完全不同。如果Framework直接调用内核驱动,那每换一个厂商,Google就得改一次Framework代码。这显然不现实。

所以HAL层定义了一套标准接口。厂商只需要实现这些接口,Framework就可以统一调用。比如Camera HAL,定义了 open()startPreview()takePicture() 等函数。

我记得在Android 8.0之前,HAL是以共享库(.so)的形式直接加载到系统服务进程中的。这导致一个问题:如果HAL崩溃,整个系统服务也跟着挂。后来Treble项目把它改成了HAL Server,独立进程运行,互不影响。

避坑指南:调试HAL层时,千万不要直接修改内核驱动来验证问题。我曾经这么干过,结果把设备搞成砖了。正确的做法是:先确认HAL接口是否被正确调用,用 adb shell lshal 查看当前设备支持的HAL服务。

1.2.3 系统服务层(System Services)

这一层是Android的核心大脑。它运行在System Server进程中,里面包含了上百个服务。

常见的系统服务有:

服务名称职责
ActivityManagerService (AMS)管理Activity生命周期、进程调度
WindowManagerService (WMS)管理窗口、触摸事件分发
PackageManagerService (PMS)管理App安装、卸载、权限
SurfaceFlinger合成所有应用的UI图层,输出到屏幕
AudioFlinger音频混音和输出

这些服务之间通过Binder通信。比如你打开一个App,AMS会通知WMS创建窗口,WMS再通知SurfaceFlinger开始渲染。

调试时,我经常用 adb shell dumpsys 来查看各个服务的状态。比如 dumpsys activity 可以看当前运行的Activity栈,dumpsys window 可以看窗口层级。

1.2.4 应用框架层(Application Framework)

这一层是给App开发者用的。它封装了系统服务的调用,提供了一套Java API。

比如你想在屏幕上显示一个按钮,你只需要写 new Button(context),Framework会帮你调用WMS去创建窗口、调用SurfaceFlinger去渲染。

常见的框架组件:

  • Activity:用户界面的基本单元
  • Service:后台任务
  • ContentProvider:数据共享
  • BroadcastReceiver:广播接收
  • View系统:UI绘制和事件处理

我个人觉得,Framework层是Android最复杂的一层。因为它既要向上提供简洁的API,又要向下管理复杂的系统服务。很多性能问题,比如界面卡顿,根源都在这一层。

1.2.5 应用层(Application Layer)

这就是你写的App了。它运行在应用进程中,每个App默认有一个独立的进程和用户ID(UID)。

应用层通过Framework API与系统交互。比如:

// 启动一个Activity
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

// 底层发生了什么?
// 1. 当前App通过Binder调用AMS
// 2. AMS检查Intent和权限
// 3. AMS通知WMS创建窗口
// 4. AMS启动SecondActivity的进程(如果未启动)
// 5. SecondActivity执行onCreate()

你看,一个简单的 startActivity(),背后经历了这么多层。这就是分层架构的魅力:每一层只关心自己的事,通过标准接口协作

1.3 各层核心职责与交互:一张图看懂

为了让你更直观地理解,我画了一个交互流程图:

用户触摸屏幕
    ↓
应用层 (App) 捕获触摸事件
    ↓ 通过Binder
应用框架层 (Framework) 解析事件,调用WMS
    ↓ 通过Binder
系统服务层 (WMS) 处理窗口焦点,通知SurfaceFlinger
    ↓ 通过HAL接口
硬件抽象层 (HAL) 调用GPU驱动
    ↓ 通过内核驱动
Linux内核层 驱动GPU渲染,输出到屏幕

这个过程中,每一层都可能成为性能瓶颈。比如:

  • 如果App层主线程做了耗时操作,触摸事件会延迟处理
  • 如果Framework层Binder通信阻塞,窗口无法及时更新
  • 如果HAL层驱动有bug,渲染会卡顿或花屏

调试技巧:遇到卡顿问题时,我习惯先用 adb shell dumpsys gfxinfo 查看App的帧率,再用 adb shell dumpsys SurfaceFlinger 看合成耗时,最后用 adb shell dumpsys meminfo 看内存情况。逐层排查,定位问题。

1.4 总结:为什么你要理解架构分层?

说白了,搞懂Android架构分层,不是为了考试,而是为了快速定位问题

你想想看,一个App崩溃了,原因可能出在哪一层?

  • 如果是NullPointerException,大概率是App层代码问题
  • 如果是TransactionTooLargeException,可能是Binder通信数据量过大
  • 如果是SurfaceFlinger hang住,可能是HAL层驱动死锁

没有分层思维,你就像无头苍蝇一样乱撞。有了分层思维,你就能快速缩小排查范围

嗯,这节课就到这里。下一节我们深入Linux内核层,聊聊Binder驱动的实现细节。到时候我会分享一个我当年调试Binder死锁的案例,保证让你印象深刻。

记住:架构是地图,调试是导航。没有地图,导航就是瞎转悠。