系统原理 / Binder / Handler / 启动流程 — 知识详解
更新: 5/15/2026 字数: 0 字 时长: 0 分钟
Binder 与 Handler 原理内容较多,已拆分为独立文件:
- binder-handler-deep.md — Binder 驱动层 mmap 源码、线程池、AIDL oneway/in/out/DeathRecipient、Handler epoll 机制、同步屏障源码、IdleHandler 详解、App 启动流程源码级分析
- surfaceflinger-display-deep.md — SurfaceFlinger 与显示系统(Surface/Buffer/BufferQueue/Layer/Canvas 关系、VSYNC 与 Choreographer、软件绘制 vs 硬件加速、双缓冲与三缓冲、合成流程、SurfaceView vs TextureView)
1. Android 系统架构
┌─────────────────────────────────┐
│ 应用层 (App Layer) │ 各种 App
├─────────────────────────────────┤
│ Framework 层 (Java API) │ AMS, WMS, PMS, ContentProvider
├─────────────────────────────────┤
│ Native 层 (C/C++ Libraries) │ SurfaceFlinger, MediaServer, Binder Driver
├─────────────────────────────────┤
│ HAL (硬件抽象层) │ Camera HAL, Audio HAL
├─────────────────────────────────┤
│ Linux Kernel │ Binder 驱动, 进程管理, 内存管理
└─────────────────────────────────┘2. Binder 机制
2.1 为什么用 Binder?
Linux 已有的 IPC 方式:管道、Socket、共享内存、信号量。
Binder 的优势:
- 性能:只需一次数据拷贝(mmap),Socket 需要两次,共享内存零拷贝但同步复杂
- 安全:内核层面验证调用方的 UID/PID,不可伪造
- 易用:C/S 架构,面向对象的调用方式
2.2 一次拷贝原理(mmap)
发送进程用户空间 → 内核缓冲区(copy_from_user,一次拷贝)
↕ mmap 映射
接收进程用户空间(直接访问,零拷贝)传统 IPC(如 Socket):发送方 → 内核 → 接收方(两次拷贝)。 Binder:接收方的用户空间和内核缓冲区通过 mmap 映射到同一块物理内存,所以数据从发送方拷贝到内核后,接收方可以直接访问,只需一次拷贝。
2.3 AIDL 生成代码分析
// IMyService.aidl
interface IMyService {
String getData(int id);
}编译后生成:
public interface IMyService extends IInterface {
// Stub:服务端实现(Binder 本地对象)
public static abstract class Stub extends Binder implements IMyService {
private static final String DESCRIPTOR = "com.example.IMyService";
static final int TRANSACTION_getData = IBinder.FIRST_CALL_TRANSACTION + 0;
public Stub() { attachInterface(this, DESCRIPTOR); }
// 关键:判断是否同进程
public static IMyService asInterface(IBinder obj) {
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IMyService) {
return (IMyService) iin; // 同进程,直接返回 Stub
}
return new Proxy(obj); // 跨进程,返回 Proxy
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
switch (code) {
case TRANSACTION_getData:
data.enforceInterface(DESCRIPTOR);
int id = data.readInt();
String result = this.getData(id); // 调用真正的实现
reply.writeString(result);
return true;
}
return super.onTransact(code, data, reply, flags);
}
// Proxy:客户端代理(Binder 代理对象)
private static class Proxy implements IMyService {
private IBinder mRemote;
@Override
public String getData(int id) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
data.writeInt(id);
mRemote.transact(TRANSACTION_getData, data, reply, 0); // 跨进程调用
reply.readException();
return reply.readString();
} finally {
data.recycle();
reply.recycle();
}
}
}
}
}调用流程:客户端 Proxy.getData() → transact() → Binder 驱动 → 服务端 Stub.onTransact() → getData() 实现
2.4 ServiceManager
ServiceManager 是 Binder 的"DNS",管理所有系统服务的注册和查找:
// 注册服务
ServiceManager.addService("activity", activityManagerService);
// 查找服务
IBinder binder = ServiceManager.getService("activity");
IActivityManager am = IActivityManager.Stub.asInterface(binder);ServiceManager 自身的 Binder 引用(handle=0)是所有进程都知道的,所以可以作为入口查找其他服务。
3. Handler 机制
3.1 核心组件
Handler → 发送/处理消息
Message → 消息载体(what, obj, arg1, arg2, target, callback)
MessageQueue → 消息队列(按 when 排序的单链表)
Looper → 循环取消息(一个线程只有一个 Looper)3.2 消息循环
// Looper.loop() 核心逻辑
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for (;;) {
Message msg = queue.next(); // 可能阻塞(epoll_wait)
if (msg == null) return; // null 表示 quit
msg.target.dispatchMessage(msg); // 分发给 Handler
msg.recycleUnchecked(); // 回收到消息池
}
}3.3 MessageQueue.next() 与 epoll
Message next() {
int nextPollTimeoutMillis = 0;
for (;;) {
nativePollOnce(ptr, nextPollTimeoutMillis); // 阻塞,底层 epoll_wait
synchronized (this) {
final long now = SystemClock.uptimeMillis();
Message msg = mMessages; // 队列头部
if (msg != null) {
if (now < msg.when) {
// 还没到执行时间,计算等待时间
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// 取出消息
mMessages = msg.next;
return msg;
}
} else {
nextPollTimeoutMillis = -1; // 无消息,无限等待
}
// 处理 IdleHandler
for (IdleHandler idler : mIdleHandlers) {
if (!idler.queueIdle()) {
mIdleHandlers.remove(idler);
}
}
}
}
}epoll 机制:Linux 的 IO 多路复用。MessageQueue 底层通过 eventfd + epoll 实现阻塞/唤醒:
- 无消息时
epoll_wait阻塞,不消耗 CPU - 有新消息时通过
eventfd写入唤醒 epoll
3.4 同步屏障
同步屏障是一个 target 为 null 的特殊 Message,插入队列后,next() 会跳过所有同步消息,优先处理异步消息。
// 发送同步屏障(hide API)
int token = queue.postSyncBarrier();
// 异步消息
Message msg = Message.obtain();
msg.setAsynchronous(true); // 标记为异步
handler.sendMessage(msg);
// 移除同步屏障
queue.removeSyncBarrier(token);应用场景:ViewRootImpl 在 scheduleTraversals() 时发送同步屏障,确保 UI 绘制的异步消息优先执行,不被其他同步消息阻塞。
3.5 IdleHandler
当 MessageQueue 空闲时(没有消息或下一条消息还没到时间)执行:
Looper.myQueue().addIdleHandler {
// 空闲时执行,适合做延迟初始化
doSomeLazyInit()
false // 返回 false 执行一次后移除,true 保持
}应用:GC、Activity 销毁(ActivityThread 中)、延迟初始化。
4. App 启动流程
4.1 完整流程
1. Launcher 调用 startActivity
2. 通过 Binder 调用 AMS.startActivity
3. AMS 检查权限、解析 Intent、确定目标 Activity
4. AMS 发现目标进程不存在,通过 Socket 通知 Zygote fork 新进程
5. Zygote fork 子进程
6. 子进程执行 ActivityThread.main()
7. ActivityThread 创建 Looper、Handler
8. 通过 Binder 调用 AMS.attachApplication,告知 AMS 进程已就绪
9. AMS 通过 Binder 回调 ApplicationThread.bindApplication
10. ActivityThread.handleBindApplication:
- 创建 Application 对象
- 创建 ContentProvider 并调用 onCreate
- 调用 Application.onCreate
11. AMS 通过 Binder 回调 ApplicationThread.scheduleLaunchActivity
12. ActivityThread.handleLaunchActivity:
- 创建 Activity 对象
- 调用 Activity.attach(创建 PhoneWindow)
- 调用 Activity.onCreate
- 调用 Activity.onStart、onResume
13. Activity.onResume 后创建 ViewRootImpl
14. ViewRootImpl.performTraversals 执行首帧绘制4.2 Zygote
Zygote 是所有 App 进程的父进程:
- 预加载了常用类和资源(Framework 类、系统资源)
- fork 时子进程直接继承这些预加载内容(COW,Copy-On-Write)
- 通过 Socket(不是 Binder)接收 fork 请求
为什么用 Socket 不用 Binder?Binder 是多线程的,fork 多线程进程会导致死锁(子进程只有一个线程,但锁状态被复制了)。
5. Activity 启动流程
App 进程 system_server 进程
startActivity()
→ Instrumentation.execStartActivity
→ AMS.startActivity (Binder) ──→ AMS.startActivityAsUser
→ ActivityStarter.execute
→ 解析 Intent、检查权限
→ 确定 Task 和启动模式
→ 暂停当前 Activity
←── ApplicationThread.schedulePauseActivity
handlePauseActivity
→ Activity.onPause
→ AMS.activityPaused (Binder) ──→ AMS 继续启动目标 Activity
←── ApplicationThread.scheduleLaunchActivity
handleLaunchActivity
→ Activity.onCreate/onStart/onResume6. 多进程
6.1 使用场景
- WebView 独立进程(避免内存泄漏影响主进程)
- 推送 Service 独立进程(保活)
- 大内存操作独立进程(图片处理、视频编辑)
6.2 多进程问题
- 静态变量不共享(每个进程有独立的虚拟机)
- SharedPreferences 不可靠(文件锁不够)
- Application 会创建多次(每个进程一次)
- 单例失效
6.3 跨进程通信方式
| 方式 | 特点 |
|---|---|
| Binder (AIDL) | 性能好,支持双向通信 |
| ContentProvider | 适合数据共享 |
| Messenger | 基于 Handler,串行处理 |
| Socket | 灵活但开销大 |
| 文件/MMKV | 简单数据共享 |
7. WMS(WindowManagerService)
7.1 职责
WMS 管理所有 Window 的:
- 添加、删除、更新
- Z-order 排序(决定哪个 Window 在上面)
- 输入事件分发(确定事件发给哪个 Window)
- 窗口动画
- Surface 管理
7.2 Window 添加流程
WindowManager.addView(view, params)
→ WindowManagerGlobal.addView
→ 创建 ViewRootImpl
→ ViewRootImpl.setView
→ IWindowSession.addToDisplay (Binder)
→ WMS.addWindow
→ 创建 WindowState
→ 分配 Surface7.3 与 AMS 的关系
- AMS 管理 Activity 的生命周期和 Task 栈
- WMS 管理 Activity 对应的 Window 的显示
- Activity 启动时,AMS 通知 WMS 创建 Window;Activity 销毁时,AMS 通知 WMS 移除 Window
8. SurfaceFlinger
8.1 职责
SurfaceFlinger 是 Android 的合成器(Compositor),负责将多个 Surface(Window)合成为最终的屏幕画面。
8.2 渲染流程
App 进程 SurfaceFlinger 显示器
┌──────────┐ ┌──────────────┐ ┌──────┐
│ 绘制到 │ BufferQueue │ 合成所有 │ │ │
│ Surface │ ──────────→ │ Surface 层 │ ────────→ │ 显示 │
│ (GPU渲染) │ │ (HWC/GPU合成) │ │ │
└──────────┘ └──────────────┘ └──────┘- 每个 Window 有自己的 Surface 和 BufferQueue
- App 通过 BufferQueue 的生产者端提交帧
- SurfaceFlinger 通过消费者端获取帧
- 使用 HWC(Hardware Composer)或 GPU 合成所有层
- VSYNC 信号同步:App 在 VSYNC 时开始绘制,SurfaceFlinger 在下一个 VSYNC 时合成
8.3 三重缓冲
Buffer A: App 正在绘制
Buffer B: SurfaceFlinger 正在合成
Buffer C: 显示器正在显示三重缓冲避免了 App 和 SurfaceFlinger 互相等待,减少掉帧。
9. PMS 与权限系统
9.1 PackageManagerService
PMS 管理所有已安装应用的信息:
- 解析 AndroidManifest.xml
- 管理权限声明和授予
- 处理 Intent 解析(查找匹配的 Activity/Service/Receiver)
- 管理应用安装/卸载/更新
9.2 运行时权限(Android 6.0+)
// 检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// 是否需要解释
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
// 显示解释对话框
}
// 请求权限(推荐使用 ActivityResult API)
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
}权限分类:
- 普通权限:安装时自动授予(INTERNET、VIBRATE)
- 危险权限:运行时请求(CAMERA、LOCATION、STORAGE)
- 特殊权限:需要跳转设置页(SYSTEM_ALERT_WINDOW、WRITE_SETTINGS)
权限组:同一组内授予一个权限后,组内其他权限自动授予(Android 11+ 不再自动授予)。
