2025/12/22 15:34:57
网站建设
项目流程
网站用的服务器是什么,WordPress添加在线商店,wordpress 制作瀑布流单页,湛江免费企业建站文章摘要
本文用通俗易懂的方式解析Android操作系统架构#xff0c;将其形象比喻为一栋四层大楼#xff1a;顶层是应用层#xff08;各类App#xff09;#xff1b;中间两层是应用框架层#xff08;系统服务#xff09;和系统库运行时#xff08;基础设施#xff09;将其形象比喻为一栋四层大楼顶层是应用层各类App中间两层是应用框架层系统服务和系统库运行时基础设施底层是Linux内核地基。文章重点阐述各层功能及协作关系如App通过框架层调用系统服务再经Native库访问内核驱动。同时解答了Android跨硬件兼容性原理以及从点击图标到界面显示的全流程系统交互帮助读者建立对Android架构的整体认知理解其分层设计思想。先说目标这篇文章想做的不是给你背一遍课本里那张“Android 系统架构四层图”而是用尽量接地气的话把下面几个问题讲清楚你手里的安卓手机看上去就是刷视频、回微信、玩游戏。但背后其实是一个挺复杂的大系统要管应用怎么装、怎么跑、怎么互相隔离要管电量、内存、网络、摄像头、传感器还要防护安全、控制权限、保证不卡太死。这些东西如果全堆一起写成一坨那软件早就烂掉了。所以 Android 一开始就做了一个非常关键的选型基于 Linux 内核 分层架构 组件化服务。你可以把它想象成一栋大楼最地下Linux 内核负责最底层“土地”和“地基”进程、内存、驱动…地下一层C/C 系统库 HAL 硬件抽象层连通内核和上层世界中间几层Android RuntimeART/Dalvik、Framework各种系统服务楼上你看得见的 AppActivity、Service、Broadcast、ContentProvider…这篇文章就带你从上到下、从外到内把这栋楼好好逛一遍先整体看Android 标准架构一张图App 层你写的代码到底跑在谁的头上Framework 层系统服务的大管家们怎么协同Runtime 层ART / Dalvik 虚拟机干嘛用Native 层C/C 的那些库为啥都长在这HAL 层OEM 厂商怎么在同一套 Android 上玩出不同硬件Linux 内核层Android 为什么选 Linux当年加了哪些 Android 特性整体设计哲学为什么要这样分层优缺点在哪对应用开发者有什么实在影响一、Android 架构概览先有一整张“大地图”教科书级的官方图你可能看过类似这样的用文字描述一下最底层Linux KernelLinux 内核往上一层Hardware Abstraction LayerHAL硬件抽象层旁边躺着一堆用 C/C 写的Native Libraries比如 libc、OpenGL、WebKit、Media 等再上一层Android RuntimeART / Dalvik Core Libraries再往上Application FrameworkJava/Kotlin 的各种系统服务ActivityManager、PackageManager、WindowManager、Telephony 等顶层Applications系统应用 三方应用电话、短信、浏览器、微信、抖音…简单类比一下Linux Kernel地基 水电总阀门HAL各种“转换器”和“适配器”让不同硬件都能接上标准接口Native Libraries水电设备、锅炉、空调机组音视频、图形、数据库等底层库Runtime一个房间里统一的“电压标准”和“插座形状”虚拟机 核心库Framework楼里各个管理处物业、保安、清洁、前台Apps住户游戏、应用通过物业提供的服务生活这就是 Android 的大框架。二、最上层应用层Applications——你摸得到的世界这层就是你最熟的地方系统应用电话、通讯录、短信、相机、设置、浏览器…第三方应用微信、抖音、微博、淘宝、游戏等等从架构视角看应用层有几个特点每个 App 是一个独立的 Linux 进程进程名一般为包名如com.example.app每个进程有自己的 UID用户 ID通过 Linux 权限机制隔离进程之间默认不能随便读写对方文件、内存App 主要用 Java/Kotlin 写逻辑层部分会用到 C/CNativeJava/Kotlin 代码运行在 ART 虚拟机上C/C 通过 JNI 调用比如游戏用 C 的图形引擎App 并不是“想干什么就干什么”而是要通过 Framework 提供的 API 来做事比如启动 Activity / Service要找 ActivityManagerService发通知要走 NotificationManager获取定位要走 LocationManager同时受权限系统控制可以这样理解App 并不是在直接动“系统地基”而是在“楼上租的房间”所有水电煤、物业服务都必须通过“大楼统一的管理中心”来申请这就是下文要讲的 Application Framework。三、Application FrameworkAndroid 系统服务的大脑这一层就是 Android 架构的核心大脑。所有 App 做“系统级操作”都要通过这里的 API。3.1 Framework 主要包括什么你在 app 里常用的android.*API就是这一层暴露出来的“外壳”。背后对应的是一个个“系统服务”多运行在system_server进程中。常见的服务有ActivityManagerService (AMS)管理四大组件Activity、Service、BroadcastReceiver、ContentProvider处理生命周期onCreate/onStart/onResume/onPause/OnStop 等负责任务栈、最近任务列表、多任务切换PackageManagerService (PMS)管理应用安装、卸载、更新解析 APK 的 AndroidManifest.xml处理权限声明uses-permissionWindowManagerService (WMS)管理所有窗口Activity、对话框、Toast 等决定谁在上面、谁在下面、如何布局和 SurfaceFlinger 协作完成绘制LocationManagerService定位服务NotificationManagerService通知栏管理TelephonyManagerService电话、短信等PowerManagerService电源、休眠、亮屏灭屏BatteryService / AlarmManagerService / InputManagerService等等这些服务的共性运行在系统进程system_server中对外通过 Binder 提供 IPC进程间通信接口提供给 App 的 Java API本质上是这些服务的“代理类”3.2 Framework 为什么这么设计你可以把 Framework 看成一座大楼里的“总物业管理中心 各职能部门”。AMS管理入住/搬家/打扫Activity 生命周期WMS管你窗户怎么开、谁挡谁PMS管你能不能入住安装应用、有没有资质权限其他服务电、网、电话、安保…这样做有几个明显好处集中控制便于策略统一比如后台进程太多了AMS 可以统一根据内存情况 kill 一部分WMS 可以根据前台应用优先级决定绘制顺序权限可控防止 App 为所欲为App 想打电话 → TelephonyManagerService 检查权限、运营商状态App 想访问通讯录 → 通过 ContentProvider 权限判断底层变化上层 API 尽量保持稳定比如硬件厂商更换底层驱动只要 HAL 层适配好了Framework 层不必大改App 层使用的 API 尽量保持兼容性3.3 Framework 和 App 是怎么“说话”的通信机制的关键字BinderApp 里的 Java API 调用 → 通过 Binder 代理 → 跨进程调用 Framework 里的 Service → 再往 Native / HAL / Kernel 层走大致过程App 调用Context.startActivity()ActivityManagerJava 封装把请求透给 AMSActivityManagerService两者不在同一个进程通过 Binder IPC 进行通信AMS 决定如何启动目标 Activity可能在另一个进程最终调度新进程、调用应用中的 Activity 对象的生命周期方法重要点Framework 层通过 Binder 实现了一套“远程调用”的机制对 App 来说看起来就像本地调用 Java 方法不需要自己写 socket 或管 IPC。四、Android RuntimeART / Dalvik这个虚拟机干嘛的Android Runtime 这一层主要有两部分ART/Dalvik 虚拟机执行字节码核心 Java 类库如java.lang,java.util,android.os等基础库4.1 为什么需要虚拟机如果让你直接在 Linux 上写 C/C 应用一样可以跑但有几个问题用 C/C 写大规模应用容易出各种内存错误泄漏、越界、悬垂指针各种 CPU 架构ARM、x86、MIPS…每个平台都要重新编译安全隔离更难容易出现程序把系统搞崩的情况Java和后来的 Kotlin 虚拟机的方案好处是一份字节码多平台执行改善内存安全GC 垃圾回收更容易做沙箱限制应用哪些 API 可以用所以 Android 把 App 的大部分逻辑放在 Java/Kotlin 虚拟机上跑。4.2 Dalvik vs ART简略差别早期 Android 使用的是Dalvik VM后来被ARTAndroid Runtime取代。简单对比Dalvik主要用JITJust-In-Time即时编译或者解释执行每次运行时把部分字节码编成机器码ART加入AOTAhead-of-Time预编译 JIT 混合模式安装应用时就把大部分字节码预编译为本地机器码.oat 文件运行时按需要动态优化目的提升启动速度、运行速度降低电量消耗更好控制内存和 GC 的行为4.3 Runtime 在架构中的位置App 的 Java/Kotlin 代码 → 编译成 .dex 字节码 → 由 ART 加载并执行ART 通过 JNI 调用 Native LibrariesART 自己也依赖 Linux 提供的低层操作线程、内存、信号等你可以把 ART 想象成一层“统一电压 插口标准”的适配器上面所有 App 插上来都能用底下真正供电的还是 Linux 硬件。五、Native LibrariesC/C 世界里的“功能机房”这一层主要是用 C/C 写的一堆库高性能、紧贴硬件。Android 中很多关键功能其实都在这里实现只是在上面包了一层 Java 外壳。常见的 Native 库libcBionicAndroid 自己的 C 运行库轻量版的 glibclibm数学库OpenGL ES图形渲染相关WebKit / Blink浏览器渲染引擎早期 WebKit现在多 Chromium/BlinkSQLite轻量级数据库libmedia / libaudio / libcamera音视频、音频输出、摄像头访问等SSL / Crypto安全加密库大部分系统服务和 App用 Java 调一圈后最终会落到这些 Native 库来干活。比如你用MediaPlayer播放视频 → Java API → 底下是 C/C 实现的解码和渲染你用Canvas画东西 → Java API → 最终调 OpenGL ES / Skia 之类的底层库为什么要用 C/C性能需求高音视频解码、图形渲染调度等需要直接操作硬件和内核接口C/C 生态里已经有成熟的现成库比如 SQLiteNative 层是 Java 世界和内核世界之间的重要桥梁。六、HAL硬件抽象层OEM 厂商的“适配器”Android 要跑在各种硬件上不同的 CPUARM、x86…不同的屏幕、摄像头、传感器、指纹、NFC、音频芯片…如果直接让 Framework 调内核驱动那每家的驱动长得一模一样这不现实。于是 Android 设计了一个中间层HALHardware Abstraction Layer。6.1 HAL 是干啥的一句话把“硬件细节”藏起来给上层提供统一、标准的接口。Google 定义“一套接口规范”比如摄像头 HAL 要提供哪些函数、音频 HAL 要提供哪些接口设备厂商OEM按照这个规范用 C/C 实现对应的 HAL 模块Framework 调 HAL不管底下用的是哪家的摄像头/音频芯片好比你在厨房想烧水不需要管楼里到底是电水壶还是燃气热水器只要你打开龙头就有热水 —— HAL 把“热水设备”抽象成统一接口。6.2 HAL 和内核驱动的关系通常最底下是内核驱动Kernel Driver直接操作硬件寄存器、DMA 等上面是 HAL 模块封装驱动操作提供更高级的接口给 Framework / Native Libraries 调用示意流程比如摄像头App → Camera API (Java) → CameraService (Framework) → Camera HAL (C) → Kernel Driver → 硬件这样做的好处Android 系统升级Framework API 稳定底层只要 HAL 适配正确不需要大改不同厂商可以用自家的硬件只要实现相同 HAL 接口就行安全边界更清晰内核驱动不直接暴露给 App 层七、最底层Linux 内核——Android 的地基Android 运行在一个定制版本的 Linux 内核之上。选择 Linux 有几个好处多用户、安全机制成熟UID/GID进程管理、内存管理、调度器、电源管理都很成熟驱动生态丰富方便硬件厂商开发7.1 Android 对 Linux 做了哪些强化/定制早期特别是 2.x/3.x 时代Android 给 Linux 加了一堆 patches补丁比如Binder IPC 机制高效的进程间通信框架支撑上层所有 Service 的调用有点类似轻量版 RPC结合了内存映射和引用计数Ashmem匿名共享内存一种特殊的共享内存机制支持按需释放用于 App 之间共享数据减轻内存压力Wakelock 电源管理粒度更细的“唤醒锁”防止设备在不合适时休眠后来这块逐步上游化或改造低内存杀手Low Memory Killer / LMKDAndroid 自己的内存回收策略用来根据内存压力自动杀后台进程上层 AMS 会与之协作后来随着 Android 成熟很多特性合入主线 Linux 内核或被替换重构。7.2 Linux 内核在架构里的角色核心职责进程 线程调度内存管理 虚拟内存文件系统网络协议栈安全机制SELinux 等各种硬件驱动你可以认为Linux 内核 整个系统的“地基 水电 安保队”其上所有东西HAL、Native Libs、Runtime、Framework、Apps都是住进来的租户。八、Android 整体架构的设计哲学为什么要这么分层说到这里可以总结一下这套架构设计背后的三个主要目标可移植性 硬件抽象Android 想跑在各种设备手机、平板、电视、车机、手表…Linux 内核HAL让硬件差异被隔离在底层Framework 和 Apps 尽量重用安全 隔离Linux 用户/进程隔离 SELinuxApp 沙箱 权限系统 Binder 控制Framework 集中控制系统资源App 不能直接摸硬件和内核可演进 可维护Framework 提供稳定 APIApp 开发者跟着 API 做内部各层可以逐步升级与优化Dalvik - ART、Binder 改良、驱动更新顺带带来的好处厂商可以在不破坏整体架构的前提下定制系统UI、系统级应用、部分 Framework 扩展谷歌可以通过 CTS/兼容性测试套件控制 Android 碎片化程度当然也有代价复杂度高学习曲线陡不同版本 Android/不同厂商的系统差异会造成兼容问题多层抽象带来一定性能损耗但通过优化和硬件提升大多可以接受九、对应用开发者来说到底哪些是“必须理解”的很多做 App 的同学会说“我又不写驱动、不改内核架构这么底层的东西知道有什么用”其实有几个方面对你非常有帮助9.1 理解“为什么很多事只能主线程做”比如UI 更新必须在主线程很多系统 API 只能在主线程调用原因Framework 的很多 Service 调用以及与 Window/输入系统的交互都绑定在特定线程UI 绘制和事件循环本身是单线程模型理解这一点你就会知道为什么要用 Handler/Looper 切回主线程知道做耗时操作要放到子线程避免阻塞主线程事件循环9.2 理解“进程/内存管理”有助于优化性能知道几件事每个 App 是独立进程有自己的虚拟机实例系统根据内存压力会杀后台进程Service/Activity 不一定一直在内存随时可能被回收这会影响你怎样合理使用 Service、BroadcastReceiver、JobScheduler怎样避免在静态变量/单例中持有大对象容易内存泄漏为什么要注意 onSaveInstanceState、onRestore 等生命周期9.3 理解“Binder 和系统服务”有助于调试问题比如调用 ContentProvider 其实是在走跨进程调用频繁调用系统服务比如频繁的 ContentResolver 查询会有性能成本出现 “Binder Transaction Failed” 之类错误时你知道这是 IPC 数据太大 / 事务失败你可以更有意识地减少大对象在 Binder 中传递比如不用 Intent 传巨大 Bitmap分批读取数据避免单次查询过重9.4 理解 HAL/内核对“兼容性”的影响写 App 时不同厂商设备摄像头、传感器表现稍有差异某些特性如双摄、特殊屏幕其实是厂商在 HAL / Framework 做的扩展你就能理解为什么同一个 API 在不同机型上的行为有差异为什么要多做机型适配、容错处理为什么 Google 通过 Project Treble 等计划允许底层和上层分区更新缓解碎片化十、最后总结用一句大白话概括这套架构我们用一段“故事版”来说 Android 架构有一块地基Linux 内核上面一层是地产商预制好的“水电接口 设备机房”Native Libraries HAL再往上是物业总部Android Runtime 系统服务 Framework最上面一层是一间间你看得见的房间一个个 App。住户App不能直接自己挖地搞水电只能给物业打电话通过 Framework API Binder物业再去协调底下机房、地基把水电送上来。这样一来安全住户别乱搞也不会把整个楼搞塌可维护底下换新设备楼上住户感知不到可扩展物业可以加新服务通知栏、分屏、多用户…多样性不同楼盘厂商里可以换不同风格装修、设备只要水电接口统一就跑的是同一套 Android。当你从这个视角再看手机上跑的每一个 App就不再只是一个图标而是在一个大系统里按规矩向系统申请资源、使用服务的“租户”。理解整套 Android 架构不是为了去写内核而是你写的每一句代码、遇到的每一个系统限制都能找到“背后真正的原因”。知道哪些事肯定做不到架构限制哪些事只是“暂时不知道怎么做”。优化和调试时可以更沿着“正确的层级”定位问题。这就是 Android 操作系统架构设计背后那套有点复杂但很有逻辑的世界观。