先把结论讲清楚:
Application Framework 就是 Android 专门给 App 准备的一整套“官方服务 + 标准工具箱”。
它把底下那些硬核东西:Linux 内核、驱动、HAL、Native 库、ART…都藏起来,
然后用一堆你听得懂的 Java/Kotlin API 的形式,端到你面前。
换成人话:
对 App 开发者来说,Application Framework 就是:
Activity/Service/BroadcastReceiver/ContentProviderContext/Intent/Handler/View/Fragment- 以及一大堆
XXXManager:ActivityManager、WindowManager、LocationManager、PackageManager…
它负责的事情可以总结成一句话:
让你只用管“业务和界面”,
不用直接去和“进程、内存、硬件、Binder、驱动”这些宫斗。
这篇文章,我们从几个角度拆开讲:
- Application Framework 在整个系统架构里是“哪一层”?
- 它大致由哪些模块组成?常见的系统服务都干什么?
- 四大组件(Activity / Service / BroadcastReceiver / ContentProvider)与 Framework 的关系。
- 某些关键机制的背后:Activity 启动、Intent 分发、权限校验、进程管理。
- 系统服务之间如何协作(AMS、WMS、PMS 等是怎么配合的)。
- 这些框架设计对我们日常写 App 有什么实质影响?应该怎么顺势而为?
一、Application Framework 在整栋“Android 楼”里的位置
先把大地图画出来(文字版):
从下往上,Android 大约分:
Linux 内核层:
- 进程、线程、内存管理、文件系统、网络、驱动、Binder 驱动、wakelock、电源管理…
硬件抽象层(HAL):
- Camera HAL、Audio HAL、Sensor HAL、Fingerprint HAL 等
- 把具体硬件封装成统一接口
Native 层:
- C/C++ 系统库:bionic、OpenGL ES、libmedia、libandroid、SQLite…
- Native 守护进程:SurfaceFlinger、MediaServer、keystore 等
Runtime 层:
- ART / Dalvik 虚拟机
- Java 核心类库、垃圾回收、JIT/AOT…
Application Framework(应用框架层):
- 一堆 Java 层的系统服务(大多在
system_server进程里) - 对外暴露为各种
Manager和android.*包下的类
- 一堆 Java 层的系统服务(大多在
应用层(Apps):
- 系统应用(拨号、短信、设置)
- 第三方应用(你写的所有 APK)
你可以想象:
- 内核 / HAL / Native / Runtime = 地基 + 水电 + 管道 + 发电厂
- Application Framework = 市政府 + 各个职能部门 + 对外办事窗口
- App = 城市里的公司、商店、住户,通过这些窗口办业务
重点:
App 绝大多数时候,只跟 Application Framework 打交道,
很少(或者尽量不)直接摸底层的 Native、HAL、内核。
二、Application Framework 是些什么东西拼成的?
先用一句最通俗的话:
Application Framework = N 多“系统服务(System Services)” + 一套“组件模型 + 生命周期管理” + 一堆“基础类和工具”。
简单列一下里面的“大角色”:
负责 App 生命周期、任务栈的:
ActivityManagerService(AMS)- Java API:
ActivityManager
负责窗口和界面的:
WindowManagerService(WMS)- Java API:
WindowManager、View、ViewRootImpl
负责包管理、安装卸载的:
PackageManagerService(PMS)- Java API:
PackageManager
负责显示 / 通知 / 状态栏 的:
StatusBarManagerService、NotificationManagerService- Java API:
NotificationManager
负责存储 / 文件 / 权限判断 的:
MountService(早期)、StorageManagerService- Java API:
StorageManager、Environment
负责位置 / 传感器 的:
LocationManagerService、SensorService- Java API:
LocationManager、SensorManager
负责电话 / 短信 / 网络 的:
- Telephony 系统服务、
ConnectivityService、WifiService - Java API:
TelephonyManager、ConnectivityManager、WifiManager
- Telephony 系统服务、
负责输入法 / 剪贴板 / 声音 / 电源 等的:
InputMethodManagerService、ClipboardService、AudioService、PowerManagerService…- Java API:
InputMethodManager、ClipboardManager、AudioManager、PowerManager
还有很多,不一一列举。
核心观念是:
每一个你熟悉的
XXXManager,背后都有一个跑在系统进程里的XXXManagerService给你撑腰。
这些服务几乎都运行在一个大进程里:system_server。
它就像整个系统的“大总管”,负责资源调度、权限管理、进程管理等。
三、四大组件和 Application Framework:你写的所有页面和后台,都被它管着
Android 独有的一套东西:四大组件:
- Activity
- Service
- BroadcastReceiver
- ContentProvider
你可以理解为,Framework 给你的四种“官方角色”:
- Activity:前台界面,跟用户互动
- Service:后台服务,执行长时间操作
- BroadcastReceiver:消息收发员,接收系统/应用发出的广播
- ContentProvider:数据对外暴露的门面,比如通讯录、媒体库等
这些组件怎么“活过来”“死掉”“切换前后台”,都是 Application Framework 帮你管。
我们分别看一下它们和 Framework 的关系。
3.1 Activity:AMS + WMS 一起管的“前台角色”
AMS(ActivityManagerService)管逻辑:
- 哪个 Activity 在前台
- 任务栈结构(TaskStack):前进、后退
- 生命周期回调(onCreate/onStart/onResume/onPause/onStop/onDestroy)
WMS(WindowManagerService)管界面:
- 哪个 Window 显示在屏幕上
- Window 的层级、动画、触摸事件分发等
- 和 SurfaceFlinger 合作把画面真正画到屏幕上
你调用:
startActivity(Intent(this,DetailActivity::class.java))实际发生的是:
你所在进程通过 Binder 调 AMS,说:“我要启动 Activity X”
AMS 检查权限、任务栈、目标进程是否存在
- 如果目标 Activity 在同一个进程:发消息给你的进程,让主线程创建实例、调用生命周期
- 如果是另一进程:通过 Zygote fork / 进程管理启动新进程,然后再让那个进程创建 Activity
AMS 同时联动 WMS:告诉窗口管理,“我要展示一个新窗口了”,处理动画、切换等
整个过程看起来是一行代码,背后是多进程 + 多服务联动。
3.2 Service:AMS 管“活着没”,Binder 管“怎么调”
Service 分两类:
- 启动式 Service:
startService()/stopService() - 绑定式 Service:
bindService()/unbindService()
无论哪种方式,关键点都有:
AMS 决定:
- 这个 Service 对应哪个进程
- 它应该何时创建/销毁(调用 onCreate/onStartCommand/onDestroy)
- 是否可以在内存紧张时被杀死
Binder 决定:
- 进程 A 怎么调用进程 B 的 Service 方法
- AIDL、Messenger 等都是 Binder 上层封装
你在代码里写:
bindService(intent,conn,BIND_AUTO_CREATE)流程大致是:
- 你的进程通过 Binder 调到 AMS:“我要绑定某个 Service”
- AMS 找到目标 Service 所在的进程,如果没起来就先拉起来
- 目标进程创建 Service 实例,onCreate → onBind,返回一个 Binder 接口
- AMS 把这个 Binder 回传给你,你这边的
ServiceConnection.onServiceConnected()被回调 - 此后你就可以通过这个 Binder(通常是接口代理)远程调用 Service 中的方法
你不用管跨进程细节,Framework + Binder 全帮你搞定。
3.3 BroadcastReceiver:AMS 做“广播站台长”
广播机制的本质也是靠 AMS 管理:
- 静态广播(在 manifest 注册):系统开机时 PMS 解析 manifest 并记下来
- 动态广播(在代码里注册):由 Activity/Service 调用 AMS 注册
发送广播:
sendBroadcast(Intent("com.xx.ACTION_YYY"))流程:
- 调到 AMS 的广播管理逻辑
- AMS 根据 Action、权限、包名过滤出匹配的 Receiver 列表
- 对于每一个匹配目标:
- 如果是“已在活跃进程里”的 Receiver,就直接回调对应进程
- 如果是需要另起进程的(比如静态注册在没启动过的 App 里),就先启动相应进程,再回调 onReceive
AMS 负责控制:
- 广播是否粘性、是否有序
- 广播超时(防止 Receiver 卡死)
- 广播权限检查
3.4 ContentProvider:数据共享的大门口,由 AMS + PMS + Provider 共同协作
ContentProvider 主要负责:
- 对外暴露一套统一的数据访问接口(insert/query/update/delete)
- 系统内很多数据都通过它对外提供:通讯录、短信、媒体库等
URI 形式一般如下:
content://contacts/… content://media/external/images/…访问流程:
- App 通过
ContentResolver调用query/insert等方法 - Framework 通过 AMS/PMS 找到对应 Provider 所在的进程
- 若进程未起,先启动
- 获取 Provider 的 Binder 接口,调用对应方法
- 返回数据(通常是 Cursor)
你看到的是 ContentResolver 的几行代码,
背后是系统服务把“访问控制 + 跨进程 + 生命周期”这一大堆事都干完了。
四、系统服务大军:AMS / WMS / PMS 这些缩写到底干嘛的?
Application Framework 层的核心,可以概括为几个超级大服务。
很多源码/面试时经常提的三个缩写:
- AMS:ActivityManagerService
- WMS:WindowManagerService
- PMS:PackageManagerService
再加上:
- NotificationManagerService
- InputMethodManagerService
- PowerManagerService
- ConnectivityService
- LocationManagerService
- SensorService
- Telephony 相关服务
- …
我们挑最关键的几个,讲清楚它们各自负责啥、怎么协作。
4.1 AMS:进程 & Activity & Service & 任务栈的大总管
AMS 的职责非常多,简单说:
只要和“应用组件生命周期、进程、生死、前后台、任务栈”有关的事,
基本都归它管。
包括但不限于:
- 启动/停止 Activity(管理 Activity 栈)
- 启动/停止/绑定 Service
- 注册/发送 Broadcast
- 进程创建/死亡监控
- 内存紧张时决定杀谁(结合内核 LMK)
- 前台/后台 App 状态切换
- 记录哪些进程持有什么组件、何时可以回收
你写的startActivity/startService/bindService/sendBroadcast背后,都是在跟 AMS 说话。
AMS 有点像:
一整个商业楼的物业管理 + 消防控制中心:
哪个公司在第几层、哪家店正在营业、哪家已经关门、哪一层人太多要限制、
哪家占用太多资源要提醒甚至“请出去”。
4.2 WMS:窗口与显示系统的“城管局”
WMS 负责整个系统所有窗口(Window)的管理:
- 每个 Activity 的窗体
- 系统状态栏、导航栏
- Toast、Dialog、系统悬浮窗
- 甚至输入法窗口(软键盘)也归它管
它决定了:
- 窗口的 Z 轴顺序(谁在谁上面)
- 窗口的大小、位置
- 是否全屏、是否可触摸
- 截图、投屏时抓哪一层图像
当你的 Activity 启动时:
- AMS 同意你“逻辑上”进入前台
- WMS 帮你真正把 Window 贴上去(通过 ViewRootImpl、SurfaceFlinger 合成)
WMS 也会配合权限系统判断:
- App 有没有权限画系统级悬浮窗(如 SYSTEM_ALERT_WINDOW)
- 某些特殊窗口(锁屏界面、系统对话框)只有系统签名应用才能创建
4.3 PMS:PakageManagerService,应用安装 & 权限 & 组件信息的“档案局”
PMS 负责:
解析 APK 的
AndroidManifest.xml把里面的 Activity/Service/BroadcastReceiver/Provider 信息存入系统数据库
管理已安装应用列表
权限声明 & 授权(哪些 app 申请了哪些权限,配置了哪些 intent-filter)
提供查询入口给其他系统服务:
- 比如:
- AMS 想知道某个 Intent 能匹配哪些 Activity,就问 PMS
- Launcher 想列出所有可启动的应用图标,也问 PMS
- 比如:
当你安装一个 APK 时,PMS 做的事包括:
- 解压 APK
- 校验签名
- 解析 manifest、资源
- 把各种信息写入包管理数据库
- 通知系统其他模块有新应用安装成功(触发广播等)
App 调用:
valpm=context.packageManagervalinfo=pm.getPackageInfo(packageName,0)其实就是在让PackageManagerService帮你查档案。
4.4 其他重要服务简单过一遍
NotificationManagerService
- 管理通知栏:添加、更新、移除通知
- 决定优先级、是否展示、是否静音
- 对应的 Java API:
NotificationManager
LocationManagerService
- 统一管理 GPS、网络定位、传感器融合
- 控制定位请求频率、精度、耗电策略
- 对应 Java API:
LocationManager
SensorService
- 管理加速度计、陀螺仪、磁场、光照等传感器数据
- 提供统一的事件接口给
SensorManager
ConnectivityService / WifiService
- 管理网络连接状态、网络切换、流量统计、VPN 等
- 通过
ConnectivityManager、WifiManager暴露给 App
PowerManagerService
- 管理屏幕亮灭、休眠、唤醒、wakelock
- 对应
PowerManager给 App 提供 wakelock 接口(慎用)
你在 App 里通过getSystemService()拿到的各种XXXManager,基本就是这些 Service 的 Java proxy。
五、从“调用 API”到“系统服务响应”:一次完整的链路
我们拿一个最常见的操作:启动一个 Activity,
看看 Application Framework 背后到底做了啥。
5.1 你写的那一行代码:
startActivity(Intent(this,SecondActivity::class.java))背后大致是下面几步(简化版):
- Activity 调用了
startActivity→ 实际走到Instrumentation或ContextImpl内部 - 最终调用到
ActivityManagerService的startActivityBinder 接口 - AMS 里做的事:
- 检查:
- 调用者有没有启动这个 Activity 的权限
- M anifest 是否声明
- 解析 Intent → 查询 PMS,看看哪一个 Activity 匹配
- 处理任务栈逻辑(singleTask、singleTop 等 launchMode)
- 决定:
- 是在当前进程里创建 Activity 还是启动新进程
- 检查:
- 如果目标是新进程:
- AMS 让 Zygote fork 一个新进程
- 在新进程里创建 Application 对象,跑 Application.onCreate
- 然后调用 ActivityThread,在主线程里创建目标 Activity 实例,调用 onCreate/onStart/onResume
- 同时,AMS 通知 WMS:
- “有个新的 Activity 窗口要上来了”,
- WMS 让 ViewRootImpl 创建 Surface,配合 SurfaceFlinger 把画面显示出来。
你看到的只是:
- 页面跳过去了
onCreate/onResume被调用了
但实际上,你敲的那个 API,穿过了:
App 进程 → Runtime → Binder → AMS → Zygote → WMS → 再回到 App 进程
这一整套 Application Framework 机制,就是帮你屏蔽了这些复杂度,让你“看上去”只是在调用本地方法。
六、Application Framework 解决了哪些“大麻烦”?
如果没有 Application Framework,你会面临一大堆原始问题:
进程管理:
- App 什么时候启动 / 什么时候被杀 / 被杀后如何恢复状态?
- 系统内存紧张时,杀谁?怎么保证前台不被轻易杀?
多任务 & 页面栈:
- 多个页面之间怎么管理返回栈?
- 从别的 App 跳到你这儿再返回,栈怎么合并?
- singleTask/singleInstance 等模式如何实现?
跨进程通信:
- 不同 App 之间怎么通信?
- 系统服务怎么对多个 App 暴露统一接口?
- 权限检查如何做?
权限和安全:
- 短信、电话、通讯录、文件、摄像头、麦克风这些敏感能力,谁能用?
- 如何拦截非法访问?
- 如何给用户一个统一的授权体验?
硬件访问:
- App 绝不能直接和驱动打交道,否则乱套了
- 要有一层中间人(系统服务)对硬件能力再抽象、做统一访问控制
生命周期和状态保存:
- 屏幕旋转、内存回收、进程重启时,如何恢复 Activity 状态?
- Service 长时间运行如何不被滥用导致耗电?
- 后台限制如何执行?
Application Framework 把这些都变成:
- 一套约定俗成的组件模型(四大组件 + 生命周期回调)
- 一套清晰的系统服务 + API(XXXManager)
- 一套统一的权限和进程管理机制
你只要在这套规则下写 App,大部分“麻烦事”系统帮你兜底。
七、Application Framework 与 Binder:为什么“跨进程调用看起来像本地调用”?
有一个非常重要的点:
Application Framework 大部分“调用系统服务”的 API,其实都是在做跨进程调用,但语法像本地方法。
比如你调用:
valam=getSystemService(Context.ACTIVITY_SERVICE)asActivityManager am.getRunningTasks(1)ActivityManager在你进程里只是一个代理(Proxy)- 真正的服务逻辑在
ActivityManagerService(system_server 进程) - 你调用的方法最终会通过 Binder 驱动,跨进程发到 system_server 里执行,再把结果传回来
Application Framework 的设计目标之一就是:
让开发者感觉不到自己在跨进程,但系统内部可以强制进程隔离、安全控制。
Binder + 一层 Manager / Service 代理的组合,让这一切成为可能:
- 对你来说是面向对象的 API
- 对系统来说是安全的 IPC 通信
八、对日常开发的影响:理解 Framework 能帮你避坑和优化什么?
知道这些不是为了背面试题,更重要的是:
8.1 生命周期和进程真相:别跟系统抢“主导权”
- AMS 有权在任何“合适”的时候杀掉你的进程(尤其是后台、空进程)
- Activity 的 onPause/onStop/onDestroy 不一定都被完整调用(崩溃/杀进程)
- Service 不是“永生”的,尤其在新版本的后台限制下
所以:
不要把重要状态只放在内存里
- 进程被杀就没了
- 可以配合 ViewModel、SavedStateHandle、持久化存储
不要认为“前台 Service 就永远不会死”
- 高负载系统照样可能干掉你
- 要容错+重启逻辑(但也要注意别滥用,影响体验)
8.2 和系统抢资源的成本:多跑一个 Service,不是白给的
系统服务设计得很精细地控制:
- CPU、内存、网络、电量
- 前台/后台优先级
你开一个常驻 Service,就相当于在跟系统说:
“给我来一杯长期保温的热水。”
系统不得不:
- 让你的进程优先级变高,减少被杀概率
- 给你保留更多资源
- 但代价就是——别人可用资源变少,整体耗电上升
所以不要随意搞:
- 长轮询
- 常驻后台 Service
- 各种无脑闹钟(Alarm)
尽量用:
- JobScheduler / WorkManager(系统帮你择机执行)
- Firebase Cloud Messaging / 推送
- 合理的前台服务(有真正的用户可见需求)
8.3 权限和数据访问:顺着框架走,安全又省心
想读短信、通讯录、定位、相机等敏感数据:
- Application Framework 已经给你设计好接口和权限
- 你无需也不应该绕过这些(比如直接读数据库文件、自己搞 socket 到某底层服务)
顺着框架走的好处:
- 兼容性好:新系统版本只要保证接口不变,你的 App 就能无感升级
- 安全:权限系统、隐私规则都在框架里统一管理
九、站在更高一点的位置看:Application Framework 的“设计哲学”
把所有细节都放一边,从更高层抽象看:
Application Framework 的设计哲学,是在“灵活性”和“安全性/可控性”之间找平衡。
它想做到:
让 App 开发者只关心业务:
- 页面的写法
- 数据的逻辑
- 交互体验
- 尽量不让你直接操心“进程调度、锁、内存碎片、硬件访问”等复杂操作
又要保证系统能统一管理所有 App:
- 谁可以在后台跑
- 谁可以访问哪些数据
- 谁抢太多资源要被限流/干掉
- 谁的行为影响用户体验,要弹警告(比如耗电、频繁崩溃)
于是它提供了:
- 统一的组件模型 + 生命周期回调(让系统有“插手点”)
- 一致的 API 接口(
XXXManager、Intent、ContentResolver) - 统一的权限控制和签名机制
- “一人一屋”的进程隔离模型(每个 App 一个沙箱)
你如果顺着这套设计思路写 App,就会感觉:
- 开发效率高
- 踩坑少
- 升级 Android 版本时问题也相对容易定位
如果刻意对抗这套设计(各种黑科技绕过框架):
- 也许一时爽,但系统一升级就全崩
- 或者被系统新加的安全策略直接拦截
十、总结:用一句话记住 Application Framework 是啥
用一句尽量接地气的话来收尾:
Android 的 Application Framework,就是系统帮你准备好的那套“办事大厅 + 服务柜台 + 办事规则”。
你写的 Activity / Service / BroadcastReceiver / ContentProvider,
都是按照它的模板填写“申请表”;你用的各种
XXXManager、Intent、ContentResolver,
都是在找不同的“窗口”办事;而这些窗口背后,站着 AMS、WMS、PMS、NotificationManagerService、LocationManagerService… 这帮“公务员”,
他们帮你去调底层的电、水、气(内核、驱动、HAL、Native 库),
保证所有 App 在这座城市里井井有条地生活。
理解 Application Framework,不是为了背它有多少个类、多少个 Service,
而是为了在你写 App 时,脑子里能有这样一张地图:
- 我这行代码是在跟谁说话?
- 这个生命周期回调为什么要这样设计?
- 系统为什么在这个时机杀我进程?
- 我怎么写代码才能顺着系统的“节奏”走,而不是跟它对着干?
当你有了这张“框架地图”,很多以前觉得“玄学”的问题,就都能找到“框架层”的解释。