Android面试题——掘金-Framework之Binder(3)

一 概述

1
2
3
关于 Android Framework 中的 Binder,
面试经常考察 IPC 机制、Binder 原理、跨进程通信、安全性 等核心知识点。
以下是一些高频面试题及解析

二 面试题解答(仅供参考)

2.1 Binder 机制是什么?为什么 Android 采用 Binder 作为 IPC 方案?

1
2
3
4
5
6
7
8
9
10
1-Binder机制
Binder 是 Android 提供的一种高效的 IPC(进程间通信)机制,
用于不同进程间数据传输(如 系统服务、跨进程调用)。
Binder 基于 C/S(Client/Server)架构,由 ServiceManager 统一管理服务。

2-Binder 优势:
-高效:相比 Socket、SharedMemory、信号量,Binder 减少了内存拷贝,基于 mmap 共享内存,只拷贝一次数据。
-安全:每个进程的 UID/PID 可用于权限验证,避免 意外数据访问。
-轻量:相比 传统的 Linux IPC(管道、消息队列、共享内存),Binder 设计更简洁,且 性能更高。
-易用:Android 提供 AIDL、Messenger,开发者可以 简化 IPC 实现

2.2 Binder 进程通信的核心组件有哪些?

1
2
3
4
5
6
7
8
9
10
11
12
1-Binder 主要涉及 四大核心组件:
-Binder(驱动):Linux 内核中的 Binder 驱动,用于 进程间通信,管理 线程池 和 数据传输。
-ServiceManager:Binder 服务注册中心,管理 系统服务(如 ActivityManager、WindowManager)。
-Client(客户端):调用远程 Service,通过 Binder 代理对象(BpBinder) 发送请求。
-Server(服务端):提供 远程服务,继承 Binder(BnBinder),处理请求

2-示意图:
Client(进程 A) Kernel(Binder 驱动) Server(进程 B)
↓ ↓ ↓
BpBinder → → → → → → → Binder 驱动 → → → → → → BnBinder
↓ ↓ ↓
sendRequest() 数据拷贝(mmap) onTransact() 解析请求

2.3 Binder 是如何实现 IPC 的?

1
2
3
4
5
6
7
8
9
10
1-Binder IPC 采用 C/S 结构,完整流程如下:

-客户端 通过 ServiceManager 获取 Binder 代理对象(BpBinder)。
-客户端 调用 transact() 发送请求,Binder 驱动 拷贝数据 到服务端进程。
-服务端 解析数据,并调用 onTransact() 处理业务逻辑。
-服务端 处理完后返回数据,Binder 驱动 拷贝数据 回客户端。

2-关键 API:
-transact(int code, Parcel data, Parcel reply, int flags) → 客户端调用
-onTransact(int code, Parcel data, Parcel reply, int flags) → 服务端解析

2.4 为什么 Binder 传输数据比 Socket / SharedMemory 更快?

1
2
3
Binder 采用 mmap 共享内存 减少了一次用户态和内核态的数据拷贝,而传统 IPC(如 Socket)需要 两次拷贝。
-Socket: 进程 A → 内核 → 进程 B(两次拷贝)
-Binder: 进程 A → 进程 B(一次拷贝,更高效)

2.5 如何使用 AIDL 进行跨进程通信?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
AIDL(Android Interface Definition Language)用于 自动生成 Binder 代码,简化 IPC 实现。

AIDL 使用步骤:
1 创建 AIDL 接口(IMyService.aidl):
interface IMyService {
void sendData(String msg);
}

2 在服务端实现 AIDL:
public class MyService extends Service {
private final IMyService.Stub mBinder = new IMyService.Stub() {
@Override
public void sendData(String msg) {
Log.d("MyService", "Received: " + msg);
}
};

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
3 客户端绑定服务并调用 AIDL 方法
ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
IMyService myService = IMyService.Stub.asInterface(service);
myService.sendData("Hello Binder");
}
};
bindService(new Intent(this, MyService.class), connection, Context.BIND_AUTO_CREATE);

2.6 Binder 机制如何保证安全性?

1
2
3
4
5
Binder 提供 进程身份验证 和 权限控制,常见安全机制有:

-UID/PID 验证:Binder.getCallingUid() 和 Binder.getCallingPid() 确保请求来源可信。
-SELinux(Security-Enhanced Linux):限制进程访问 Binder 服务。
-AndroidManifest 权限声明:android:permission 限制特定应用访问服务

2.7 Binder 驱动的作用是什么?

1
2
3
4
5
Binder 驱动(/dev/binder) 负责管理 线程池、数据传输、进程间通信。

-线程池管理(线程唤醒、请求调度)。
-用户态和内核态的数据交换(mmap 共享内存)。
-进程间对象引用(BpBinder / BnBinder)。

2.8 为什么 Binder 使用 IBinder 作为通信接口?

1
2
-IBinder 统一 客户端(BpBinder)和服务端(BnBinder) 接口,封装 跨进程调用。
-通过 onTransact() 处理 跨进程数据解析,简化 IPC 逻辑。

2.9 Binder 是如何管理线程的?

1
2
3
-Binder 线程池:每个进程最多 16 个 Binder 线程(MAX_BINDER_THREADS = 16)。
-多线程并发:Binder 采用 线程池调度 处理多个请求,避免 线程阻塞。
-主线程vs.Binder 线程:主线程处理 UI 逻辑,Binder 线程池 处理远程调用。

2.10 Binder 可能导致什么性能问题?

1
2
3
-Binder 线程耗尽:如果 所有 16 个 Binder 线程 都在处理任务,新请求会 被阻塞,导致 ANR。
-Binder 数据过大:Binder 传输 数据大小受限(1MB),建议 大数据用共享内存。
-服务端阻塞:如果 onTransact() 执行耗时任务,可能导致 请求延迟,影响 UI 流畅度。

三 参考

  • 知乎—知识库的大纲