09-Binder通信机制完全解析
·
Binder通信机制完全解析
摘要
本文从Linux内核到Android Framework层面全面剖析Binder通信机制。Binder是Android系统进程间通信(IPC)的核心,贯穿四大组件、系统服务、应用进程通信的方方面面。文章将详细解析Binder驱动原理、ServiceManager服务注册与查询、AIDL编译产物、Binder线程池管理、死亡通知机制、以及与传统IPC的对比。通过源码级分析和实战案例,帮助开发者深入理解Android跨进程通信的底层实现,掌握Binder使用的最佳实践。
关键词: Binder、IPC、AIDL、ServiceManager、Binder驱动
1. Binder概述与架构
1.1 为什么需要Binder
Android基于Linux内核,进程间内存隔离,需要IPC机制通信。传统IPC方式对比:
| 方式 | 优点 | 缺点 | 数据拷贝次数 |
|---|---|---|---|
| 管道/Socket | 通用性强 | 1. 效率低 2. 无法传递文件描述符 3. 缺乏安全机制 |
2次 |
| 共享内存 | 速度快 | 1. 需要复杂同步机制 2. 难以管理 |
0次 |
| Binder | 1. 高效(1次拷贝) 2. 安全(UID/PID验证) 3. 面向对象 4. 支持实名与匿名 |
Android专属,不跨平台 | 1次 |
1.2 Binder整体架构
1.3 Binder通信模型
2. Binder驱动原理
2.1 核心数据结构
// kernel/drivers/android/binder.c
// Binder节点(Server端实体)
struct binder_node {
int debug_id;
spinlock_t lock;
struct binder_work work;
struct rb_node rb_node; // 红黑树节点
struct hlist_head refs; // 引用列表
int internal_strong_refs;
struct binder_proc *proc; // 所属进程
void __user *ptr; // 用户空间Binder对象地址
void __user *cookie; // 附加数据
};
// Binder引用(Client端代理)
struct binder_ref {
int debug_id;
struct rb_node rb_node_desc; // 按句柄索引
struct rb_node rb_node_node; // 按节点索引
struct hlist_node node_entry;
struct binder_proc *proc; // 所属进程
struct binder_node *node; // 指向实体
uint32_t desc; // 句柄值(Client使用)
int strong;
int weak;
};
// Binder进程
struct binder_proc {
struct hlist_node proc_node;
struct rb_root threads; // 线程池
struct rb_root nodes; // 本进程的Binder实体
struct rb_root refs_by_desc; // 本进程持有的引用(按句柄)
struct rb_root refs_by_node; // 本进程持有的引用(按节点)
struct mm_struct *vma; // mmap映射的内存
struct task_struct *tsk;
struct files_struct *files;
};
// Binder线程
struct binder_thread {
struct binder_proc *proc;
struct rb_node rb_node;
struct list_head waiting_thread_node;
int pid;
int looper; // 线程状态
struct binder_transaction *transaction_stack;
};
// Binder事务(一次调用)
struct binder_transaction {
int debug_id;
struct binder_work work;
struct binder_thread *from; // 发起线程
struct binder_transaction *from_parent;
struct binder_proc *to_proc; // 目标进程
struct binder_thread *to_thread; // 目标线程
struct binder_buffer *buffer; // 数据缓冲区
unsigned int code; // 方法码
unsigned int flags;
};
2.2 内存映射机制
Binder通过mmap实现一次拷贝:
// kernel/drivers/android/binder.c
static int binder_mmap(struct file *filp, struct vm_area_struct *vma) {
struct binder_proc *proc = filp->private_data;
const char *failure_string;
struct binder_buffer *buffer;
// 限制映射大小(默认1MB-8KB)
if ((vma->vm_end - vma->vm_start) > SZ_4M)
vma->vm_end = vma->vm_start + SZ_4M;
// 分配内核缓冲区
proc->buffer = kzalloc(sizeof(*proc->buffer), GFP_KERNEL);
proc->buffer_size = vma->vm_end - vma->vm_start;
// 分配物理页
proc->pages = kzalloc(sizeof(proc->pages[0]) *
((vma->vm_end - vma->vm_start) / PAGE_SIZE),
GFP_KERNEL);
// 建立映射:用户空间地址 <-> 内核缓冲区
for (page_idx = 0; page_idx < proc->buffer_size / PAGE_SIZE; page_idx++) {
page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
proc->pages[page_idx] = page;
// 同时映射到用户空间和内核空间
ret = map_kernel_range_noflush((unsigned long)proc->buffer +
page_idx * PAGE_SIZE,
PAGE_SIZE, PAGE_KERNEL, &page);
ret = map_vm_area(vma, PAGE_KERNEL, proc->pages);
}
return 0;
}
内存布局图:
2.3 数据传输流程
// kernel/drivers/android/binder.c
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
int ret;
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
thread = binder_get_thread(proc);
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
// 从用户空间拷贝请求
if (copy_from_user(&bwr, ubuf, sizeof(bwr)))
return -EFAULT;
// 处理写入(发送数据)
if (bwr.write_size > 0)
ret = binder_thread_write(proc, thread,
bwr.write_buffer,
bwr.write_size,
&bwr.write_consumed);
// 处理读取(接收数据)
if (bwr.read_size > 0)
ret = binder_thread_read(proc, thread,
bwr.read_buffer,
bwr.read_size,
&bwr.read_consumed,
filp->f_flags & O_NONBLOCK);
// 返回结果到用户空间
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
return -EFAULT;
break;
}
case BINDER_SET_MAX_THREADS:
// 设置最大线程数
break;
}
return ret;
}
3. ServiceManager服务管理
3.1 ServiceManager架构
3.2 服务注册流程
// frameworks/native/libs/binder/IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager> {
public:
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) {
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name); // 服务名称
data.writeStrongBinder(service); // Binder对象
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// 调用ServiceManager的ADD_SERVICE_TRANSACTION
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
};
// frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::addService(const std::string& name,
const sp<IBinder>& binder,
bool allowIsolated,
int32_t dumpPriority) {
// 权限检查
if (!mAccess->canAdd(name)) {
return Status::fromExceptionCode(Status::EX_SECURITY);
}
// 存储到服务列表
mNameToService[name] = Service {
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
};
// 注册死亡通知
auto obituary = [this, name] {
mNameToService.erase(name);
};
binder->linkToDeath(new BinderCallback<decltype(obituary)>(obituary));
return Status::ok();
}
3.3 服务查询流程
// frameworks/base/core/java/android/os/ServiceManager.java
public final class ServiceManager {
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service; // 缓存命中
} else {
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IBinder rawGetService(String name) throws RemoteException {
final IBinder binder = getIServiceManager().getService(name);
// 缓存服务
if (binder != null) {
sCache.put(name, binder);
}
return binder;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 获取ServiceManager代理(句柄=0)
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
}
4. AIDL机制详解
4.1 AIDL编译流程
4.2 AIDL编译产物分析
// IMyService.aidl
interface IMyService {
int add(int a, int b);
String getName();
}
编译后生成的Java代码:
// IMyService.java(简化版)
public interface IMyService extends android.os.IInterface {
// 服务端实现基类
public static abstract class Stub extends android.os.Binder implements IMyService {
private static final java.lang.String DESCRIPTOR = "com.example.IMyService";
// 方法码
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
// 将IBinder转换为接口
public static IMyService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IMyService))) {
return ((IMyService) iin); // 本地调用(同进程)
}
return new Stub.Proxy(obj); // 远程调用(跨进程)
}
@Override
public android.os.IBinder asBinder() {
return this;
}
// 服务端接收调用
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add: {
data.enforceInterface(DESCRIPTOR);
int _arg0 = data.readInt();
int _arg1 = data.readInt();
int _result = this.add(_arg0, _arg1); // 调用实现
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_getName: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getName();
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
// 客户端代理实现
private static class Proxy implements IMyService {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
@Override
public int add(int a, int b) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
// 发起Binder调用
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public java.lang.String getName() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getName, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}
// 接口方法声明
public int add(int a, int b) throws android.os.RemoteException;
public java.lang.String getName() throws android.os.RemoteException;
}
4.3 调用流程详解
5. Binder线程池管理
5.1 线程池架构
// frameworks/base/core/java/android/os/Binder.java
public class Binder implements IBinder {
private static volatile IBinderInternal sBinderInternal;
// Binder线程池默认最大线程数
private static final int BINDER_THREADS = 16;
public static final native void setThreadStrictModePolicy(int policyMask);
public static final native void flushPendingCommands();
public static final native void joinThreadPool();
}
// frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool() {
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true); // 创建主线程
}
}
void ProcessState::spawnPooledThread(bool isMain) {
if (mMaxThreads > 0) {
sp<Thread> t = new PoolThread(isMain);
t->run(poolThreadName.string());
}
}
class PoolThread : public Thread {
virtual bool threadLoop() {
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
};
5.2 线程处理流程
// frameworks/native/libs/binder/IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain) {
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// 阻塞等待Binder事件
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
abort();
}
// 非主线程可以退出
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
status_t IPCThreadState::getAndExecuteCommand() {
status_t result;
int32_t cmd;
// 与驱动通信
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) return result;
cmd = mIn.readInt32();
// 执行命令
result = executeCommand(cmd);
}
return result;
}
status_t IPCThreadState::executeCommand(int32_t cmd) {
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
case BR_TRANSACTION: {
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
Parcel reply;
// 调用BBinder的onTransact
if (tr.target.ptr) {
sp<BBinder> b((BBinder*)tr.cookie);
error = b->transact(tr.code, buffer, &reply, tr.flags);
}
// 发送返回值
if ((tr.flags & TF_ONE_WAY) == 0) {
sendReply(reply, 0);
}
break;
}
case BR_DEAD_BINDER: {
// 处理死亡通知
break;
}
}
return result;
}
6. 死亡通知机制
6.1 死亡通知注册
// frameworks/base/core/java/android/os/IBinder.java
public interface IBinder {
public interface DeathRecipient {
void binderDied();
}
public void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
public boolean unlinkToDeath(DeathRecipient recipient, int flags);
}
// 客户端使用示例
public class MyClient {
private IMyService mService;
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
Log.e(TAG, "Service died");
// 清理资源
mService = null;
// 尝试重新连接
reconnectService();
}
};
private void bindService() {
Intent intent = new Intent(this, MyService.class);
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IMyService.Stub.asInterface(service);
try {
// 注册死亡通知
service.linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 异常断开
mService = null;
}
}, BIND_AUTO_CREATE);
}
}
6.2 驱动层死亡通知实现
// kernel/drivers/android/binder.c
static void binder_release_work(struct binder_proc *proc,
struct list_head *list) {
struct binder_work *w;
while (1) {
w = binder_dequeue_work_head(proc, list);
if (!w)
return;
switch (w->type) {
case BINDER_WORK_DEAD_BINDER:
// 发送死亡通知到客户端
break;
}
}
}
7. 实战案例
7.1 案例1:自定义AIDL服务
定义AIDL接口:
// ICalculator.aidl
package com.example;
interface ICalculator {
int add(int a, int b);
int subtract(int a, int b);
}
服务端实现:
public class CalculatorService extends Service {
private final ICalculator.Stub mBinder = new ICalculator.Stub() {
@Override
public int add(int a, int b) throws RemoteException {
return a + b;
}
@Override
public int subtract(int a, int b) throws RemoteException {
return a - b;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
客户端调用:
public class ClientActivity extends AppCompatActivity {
private ICalculator mCalculator;
private boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mCalculator = ICalculator.Stub.asInterface(service);
mBound = true;
try {
int result = mCalculator.add(5, 3);
Log.d(TAG, "Result: " + result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mCalculator = null;
mBound = false;
}
};
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, CalculatorService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
7.2 案例2:传递复杂对象
定义Parcelable对象:
// User.aidl
package com.example;
parcelable User;
// IUserManager.aidl
package com.example;
import com.example.User;
interface IUserManager {
User getUser(int id);
void saveUser(in User user);
List<User> getAllUsers();
}
// User.java
public class User implements Parcelable {
private int id;
private String name;
private int age;
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
protected User(Parcel in) {
id = in.readInt();
name = in.readString();
age = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeInt(age);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
7.3 案例3:单向调用(oneway)
// ICallback.aidl
package com.example;
oneway interface ICallback {
void onDataChanged(String data);
}
// IDataService.aidl
package com.example;
import com.example.ICallback;
interface IDataService {
void registerCallback(ICallback callback);
void unregisterCallback(ICallback callback);
}
oneway特性:
- 异步调用,不等待返回
- 不能有返回值(void)
- 不抛出RemoteException
- 适合回调通知场景
8. 性能优化与最佳实践
8.1 Binder限制
// frameworks/base/core/java/android/os/TransactionTooLargeException.java
// Binder事务大小限制:1MB
public static final int TRANSACTION_SIZE_LIMIT = 1 * 1024 * 1024;
优化策略:
- 传递大数据使用文件描述符(ParcelFileDescriptor)
- 分批传输
- 使用共享内存(MemoryFile/Ashmem)
8.2 避免主线程Binder调用
// 错误:主线程同步Binder调用可能导致ANR
mService.longRunningOperation(); // 如果超过5秒,触发ANR
// 正确:异步调用
new Thread(() -> {
try {
String result = mService.longRunningOperation();
runOnUiThread(() -> updateUI(result));
} catch (RemoteException e) {
e.printStackTrace();
}
}).start();
// 或使用Kotlin协程
lifecycleScope.launch(Dispatchers.IO) {
val result = mService.longRunningOperation()
withContext(Dispatchers.Main) {
updateUI(result)
}
}
8.3 权限验证
public class SecureService extends Service {
private final ISecureApi.Stub mBinder = new ISecureApi.Stub() {
@Override
public String getSensitiveData() throws RemoteException {
// 检查调用者权限
int uid = Binder.getCallingUid();
int pid = Binder.getCallingPid();
if (checkCallingPermission("com.example.SENSITIVE_PERMISSION")
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Permission denied");
}
// 检查调用者包名
String[] packages = getPackageManager().getPackagesForUid(uid);
if (!Arrays.asList(packages).contains("com.example.trusted")) {
throw new SecurityException("Unauthorized access");
}
return "Sensitive data";
}
};
}
9. 总结
9.1 Binder核心优势
- 高效:只需一次数据拷贝(vs Socket的两次)
- 安全:内核层UID/PID验证,防止伪造
- 面向对象:接口化设计,易于使用
- 稳定:线程池管理,死亡通知机制
9.2 Binder通信全流程
9.3 开发建议
- 优先使用系统AIDL工具:自动生成Stub/Proxy,减少错误
- 合理设计接口:避免频繁跨进程调用
- 控制数据大小:避免TransactionTooLargeException
- 异步调用:避免主线程阻塞
- 注册死亡通知:优雅处理进程异常
- 权限验证:保护敏感接口
Binder是Android系统的基石,理解其原理对于深入开发、性能优化、问题排查都至关重要。
参考资料:
- Android源码:
kernel/drivers/android/binder.c - Android源码:
frameworks/native/libs/binder/ - Android源码:
frameworks/base/core/java/android/os/Binder.java - Android源码:
frameworks/native/cmds/servicemanager/
更多推荐


所有评论(0)