一、Android系统架构概览:从Linux内核到应用层

做Android开发这么多年,我经常被问到同一个问题:「Android系统到底长什么样?」

说实话,刚入行那会儿我也挺懵的。每天跟Activity、Service打交道,却不知道下面几层在干什么。直到有一次排查一个内存泄漏问题,追到了Native层,才意识到——不懂架构,你连Bug都修不明白

今天我就带你把这四层架构彻底捋一遍。嗯,咱们从下往上讲。

1.1 四层架构模型总览

Android系统本质上是一个软件叠层架构。说白了,就是一层摞一层,每层各司其职,层与层之间通过固定的接口通信。

我个人习惯把这四层记成:

  • 底层:Linux内核 —— 管硬件
  • 中间层1:硬件抽象层(HAL) + 系统库 —— 管驱动和基础能力
  • 中间层2:Android运行时 + 系统服务 —— 管应用运行环境
  • 顶层:应用框架层 + 应用层 —— 管用户交互

你想想看,这其实跟盖楼是一个道理。地基不稳,楼上再漂亮也白搭。

核心观点: Android的四层架构设计,核心目标就两个——解耦复用。每一层只关心自己的事,不越界。

1.2 第一层:Linux内核层

这是Android的根基。Android选择Linux内核,不是因为它好看,而是因为Linux在硬件驱动、进程管理、内存管理上已经非常成熟。

内核层主要干这几件事:

  • 进程管理:每个Android应用都是一个独立的Linux进程
  • 内存管理:Low Memory Killer(LMK)就是内核层的机制
  • 驱动模型:显示、相机、Wi-Fi、蓝牙等硬件驱动
  • 网络栈:TCP/IP协议栈
  • 安全模型:基于Linux的UID/GID权限隔离

我在项目中遇到过一个问题:某款手机频繁闪退,查了半天发现是内核的LMK阈值设置太激进。说白了,内核层的参数调优,直接影响上层体验。

注意: Android使用的Linux内核是裁剪版,不是标准Linux。比如它没有glibc,没有X Window系统,也没有标准的Linux桌面环境。别拿桌面Linux的经验硬套。

1.3 第二层:硬件抽象层(HAL)与系统库

这一层是承上启下的关键。为什么需要HAL?

你想想看,手机厂商用的芯片五花八门——高通、联发科、展讯……如果每个厂商的驱动都直接暴露给上层,那应用开发者得疯掉。

HAL的作用就是: 定义一套统一的接口,让上层不用关心底层是谁家的硬件。

举个例子:

// HAL层定义的相机接口(简化版)
struct camera_device_t {
    int (*open)(const char *id);
    int (*close)(void);
    int (*start_preview)(void);
    int (*stop_preview)(void);
};

厂商只需要实现这个结构体里的函数指针,上层调用时根本不知道底层是哪个芯片。

系统库这边,有几个你肯定听过:

  • libc (Bionic):Android自己的C库,比glibc更轻量
  • SurfaceFlinger:负责合成所有应用的显示内容
  • MediaCodec:音视频编解码
  • SQLite:轻量级数据库引擎
  • OpenGL ES / Vulkan:图形渲染API

我曾经踩过一个坑:在某个低端机上播放视频卡顿,排查后发现是MediaCodec的硬件编解码器没走通,回退到了软件解码。嗯,这就是HAL层适配没做好的典型问题。

1.4 第三层:Android运行时与系统服务

这一层是Android最核心的部分。它包括:

  • ART (Android Runtime):负责把Dex字节码编译成机器码。从Android 5.0开始,ART取代了Dalvik。我个人觉得,ART最大的贡献就是预编译(AOT) + 即时编译(JIT)混合模式,既保证了安装速度,又提升了运行效率。
  • 核心系统服务:ActivityManagerService、WindowManagerService、PackageManagerService……这些Service是Android的「大脑」。

为什么系统服务这么重要?

你每次startActivity(),其实都是通过Binder IPC调用到ActivityManagerService,由它来决策:

  • 这个Activity该不该启动?
  • 启动在哪个进程?
  • 生命周期怎么管理?

说白了,系统服务就是Android的「中央政府」,所有应用的请求都要经过它审批。

小技巧: 调试系统服务问题时,可以用 dumpsys 命令。比如 adb shell dumpsys activity 能看到所有Activity栈的状态。这个命令我几乎天天用。

1.5 第四层:应用框架层与应用层

这一层是开发者最熟悉的。应用框架层提供了四大组件:

  • Activity:管理UI界面
  • Service:后台任务
  • BroadcastReceiver:广播接收
  • ContentProvider:数据共享

再加上View体系、资源管理、通知管理等,构成了我们每天打交道的API。

应用层就是你我写的那些App了。不管是微信、抖音,还是你自己写的小工具,都跑在这一层。

这里有个容易忽略的点:应用层和框架层的边界其实很模糊。比如你写一个自定义View,它属于应用层,但调用的Canvas、Paint这些类属于框架层。层与层之间通过BinderSocket通信。

1.6 各层交互方式

层与层之间怎么通信?我画了一张图帮你理解:

第四层:应用层 微信、抖音、你的App 第三层:应用框架层 ActivityManagerService · WindowManagerService · View体系 第二层:系统库 & 硬件抽象层 (HAL) SurfaceFlinger · MediaCodec · OpenGL ES · 相机HAL · 音频HAL 第一层:Linux内核层 进程管理 · 内存管理 · 驱动模型 · 网络栈 · 安全模型 用户空间 内核空间 Binder IPC JNI / 系统调用 系统调用

从上图你能看到:

  • 应用层 → 框架层:通过Binder IPC调用系统服务
  • 框架层 → 系统库:通过JNI(Java Native Interface)调用Native代码
  • 系统库 → 内核层:通过Linux系统调用(open/read/write/ioctl等)
  • HAL → 内核驱动:通过设备文件节点(/dev/xxx)通信

这里有个关键点:Binder是Android独有的IPC机制。为什么不用Linux自带的Socket或共享内存?因为Binder在安全性和性能上做了平衡——每次IPC调用都会校验调用方的UID,而且只拷贝一次数据。

一句话总结: Android四层架构,每一层都只做一件事。内核管硬件,HAL管抽象,运行时管执行,框架管交互。层与层之间通过Binder、JNI、系统调用三种方式通信。

1.7 我的一点经验

做Android架构师这些年,我最大的感受是:很多问题追到根上,都是跨层的问题

比如App卡顿,你以为是自己代码写得不好,其实可能是SurfaceFlinger合成效率低,也可能是内核的GPU驱动有Bug。再比如App被杀,你以为是自己内存泄漏,其实可能是LMK的阈值设置不合理。

所以我建议你:遇到疑难问题,不要只盯着自己那一层。从应用层一路往下查,每层都看一眼,往往能找到真正的根因。

嗯,这一章就讲到这里。记住这张四层架构图,后面每一章都会用到它。


公众号:蓝海资料掘金营,微信 deep3321