Android Binder C/C++ 层详解与实践
1. Binder 架构概述
1.1 Binder 驱动层架构
用户空间 (User Space)
↓
Binder Lib (libbinder.so)
↓
Binder 驱动 (binder.c)
↓
内核空间 (Kernel Space)
2. Binder 基础实例
2.1 简单的 Binder 服务端 (C++)
IBinderDemoService.h
cpp
#ifndef IBINDER_DEMO_SERVICE_H
#define IBINDER_DEMO_SERVICE_H
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/BinderService.h>
#include <utils/String8.h>
namespace android {
class IBinderDemoService : public IInterface {
public:
DECLARE_META_INTERFACE(BinderDemoService);
virtual int32_t add(int32_t a, int32_t b) = 0;
virtual String8 greet(const String8& name) = 0;
virtual status_t getVersion(int32_t* version) = 0;
};
class BnBinderDemoService : public BnInterface<IBinderDemoService> {
public:
virtual status_t onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
} // namespace android
#endif
BinderDemoService.cpp
cpp
#include "IBinderDemoService.h"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <utils/String8.h>
#define LOG_TAG "BinderDemoService"
namespace android {
enum {
ADD = IBinder::FIRST_CALL_TRANSACTION,
GREET,
GET_VERSION
};
// 实现 Binder 接口
class BinderDemoService : public BnBinderDemoService {
private:
int32_t mVersion;
public:
BinderDemoService() : mVersion(1) {
ALOGD("BinderDemoService created, version: %d", mVersion);
}
virtual ~BinderDemoService() {
ALOGD("BinderDemoService destroyed");
}
virtual int32_t add(int32_t a, int32_t b) {
ALOGD("add() called: %d + %d", a, b);
int32_t result = a + b;
ALOGD("add() result: %d", result);
return result;
}
virtual String8 greet(const String8& name) {
ALOGD("greet() called with: %s", name.string());
String8 result = String8::format("Hello, %s! from Binder Service", name.string());
ALOGD("greet() result: %s", result.string());
return result;
}
virtual status_t getVersion(int32_t* version) {
ALOGD("getVersion() called");
if (version) {
*version = mVersion;
ALOGD("getVersion() result: %d", *version);
}
return NO_ERROR;
}
};
// 事务处理实现
status_t BnBinderDemoService::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags) {
ALOGD("onTransact() code: %u", code);
switch (code) {
case ADD: {
CHECK_INTERFACE(IBinderDemoService, data, reply);
int32_t a = data.readInt32();
int32_t b = data.readInt32();
int32_t result = add(a, b);
reply->writeInt32(result);
ALOGD("ADD transaction completed, result: %d", result);
return NO_ERROR;
}
case GREET: {
CHECK_INTERFACE(IBinderDemoService, data, reply);
String8 name = data.readString8();
String8 result = greet(name);
reply->writeString8(result);
ALOGD("GREET transaction completed, result: %s", result.string());
return NO_ERROR;
}
case GET_VERSION: {
CHECK_INTERFACE(IBinderDemoService, data, reply);
int32_t version;
status_t status = getVersion(&version);
reply->writeInt32(version);
ALOGD("GET_VERSION transaction completed, version: %d", version);
return status;
}
default:
ALOGD("Unknown transaction code: %u", code);
return BBinder::onTransact(code, data, reply, flags);
}
}
// 实现接口描述符
IMPLEMENT_META_INTERFACE(BinderDemoService, "com.example.BinderDemoService");
} // namespace android
using namespace android;
int main(int argc, char** argv) {
ALOGD("=== Binder Demo Service Starting ===");
// 设置 Binder 线程池
sp<ProcessState> proc(ProcessState::self());
proc->startThreadPool();
// 创建服务实例
sp<BinderDemoService> service = new BinderDemoService();
// 注册服务到 ServiceManager
status_t status = defaultServiceManager()->addService(
String16("binder_demo_service"), service);
if (status != NO_ERROR) {
ALOGE("Failed to register binder_demo_service: %d", status);
return -1;
}
ALOGD("=== Binder Demo Service Registered Successfully ===");
ALOGD("Service name: binder_demo_service");
ALOGD("Service version: %d", service->getVersion(nullptr));
// 保持服务运行
ALOGD("Service is running, waiting for requests...");
IPCThreadState::self()->joinThreadPool();
ALOGD("=== Binder Demo Service Exiting ===");
return 0;
}
2.2 Binder 客户端 (C++)
BinderDemoClient.cpp
cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <utils/String8.h>
#include <unistd.h>
#include "IBinderDemoService.h"
#define LOG_TAG "BinderDemoClient"
using namespace android;
class BinderDemoClient {
private:
sp<IBinderDemoService> mService;
public:
BinderDemoClient() {
ALOGD("BinderDemoClient created");
}
~BinderDemoClient() {
ALOGD("BinderDemoClient destroyed");
}
bool connect() {
ALOGD("Connecting to binder_demo_service...");
sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
ALOGE("Cannot get ServiceManager");
return false;
}
sp<IBinder> binder = sm->getService(String16("binder_demo_service"));
if (binder == nullptr) {
ALOGE("Cannot find binder_demo_service");
return false;
}
mService = interface_cast<IBinderDemoService>(binder);
if (mService == nullptr) {
ALOGE("Cannot cast to IBinderDemoService");
return false;
}
ALOGD("Successfully connected to binder_demo_service");
return true;
}
void testAdd() {
if (mService == nullptr) {
ALOGE("Service not connected");
return;
}
ALOGD("Testing add function...");
int32_t a = 15;
int32_t b = 25;
int32_t result = mService->add(a, b);
ALOGD("ADD TEST: %d + %d = %d", a, b, result);
}
void testGreet() {
if (mService == nullptr) {
ALOGE("Service not connected");
return;
}
ALOGD("Testing greet function...");
String8 name = String8("Android Developer");
String8 result = mService->greet(name);
ALOGD("GREET TEST: %s", result.string());
}
void testGetVersion() {
if (mService == nullptr) {
ALOGE("Service not connected");
return;
}
ALOGD("Testing getVersion function...");
int32_t version = 0;
status_t status = mService->getVersion(&version);
if (status == NO_ERROR) {
ALOGD("VERSION TEST: Service version = %d", version);
} else {
ALOGE("Failed to get version: %d", status);
}
}
};
int main(int argc, char** argv) {
ALOGD("=== Binder Demo Client Starting ===");
// 初始化 Binder
sp<ProcessState> proc(ProcessState::self());
// 创建客户端
BinderDemoClient client;
// 连接服务
if (!client.connect()) {
ALOGE("Failed to connect to service");
return -1;
}
ALOGD("=== Starting Binder Tests ===");
// 执行测试
client.testAdd();
sleep(1);
client.testGreet();
sleep(1);
client.testGetVersion();
sleep(1);
// 批量测试
ALOGD("=== Starting Batch Tests ===");
for (int i = 0; i < 3; i++) {
ALOGD("--- Batch Test %d ---", i + 1);
client.testAdd();
client.testGreet();
sleep(1);
}
ALOGD("=== All Tests Completed ===");
ALOGD("Client exiting...");
return 0;
}
2.3 Android.bp 编译配置
Android.bp
bp
cc_binary {
name: "binder_demo_service",
srcs: [
"IBinderDemoService.h",
"BinderDemoService.cpp",
],
shared_libs: [
"libbinder",
"libutils",
"liblog",
"libcutils",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
],
}
cc_binary {
name: "binder_demo_client",
srcs: [
"IBinderDemoService.h",
"BinderDemoClient.cpp",
],
shared_libs: [
"libbinder",
"libutils",
"liblog",
"libcutils",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
],
}
3. 编译和运行
3.1 编译命令
bash
# 在 Android 源码环境中编译
mmm ./path/to/binder/demo
# 或者使用 ninja
ninja binder_demo_service binder_demo_client
3.2 运行结果分析
启动服务端:
bash
adb shell /system/bin/binder_demo_service
服务端输出:
=== Binder Demo Service Starting ===
BinderDemoService created, version: 1
=== Binder Demo Service Registered Successfully ===
Service name: binder_demo_service
Service version: 1
Service is running, waiting for requests...
运行客户端:
bash
adb shell /system/bin/binder_demo_client
客户端输出:
=== Binder Demo Client Starting ===
BinderDemoClient created
Connecting to binder_demo_service...
Successfully connected to binder_demo_service
=== Starting Binder Tests ===
Testing add function...
ADD TEST: 15 + 25 = 40
Testing greet function...
GREET TEST: Hello, Android Developer! from Binder Service
Testing getVersion function...
VERSION TEST: Service version = 1
=== Starting Batch Tests ===
--- Batch Test 1 ---
ADD TEST: 15 + 25 = 40
GREET TEST: Hello, Android Developer! from Binder Service
--- Batch Test 2 ---
ADD TEST: 15 + 25 = 40
GREET TEST: Hello, Android Developer! from Binder Service
--- Batch Test 3 ---
ADD TEST: 15 + 25 = 40
GREET TEST: Hello, Android Developer! from Binder Service
=== All Tests Completed ===
Client exiting...
服务端同时输出的事务日志:
onTransact() code: 1
add() called: 15 + 25
add() result: 40
ADD transaction completed, result: 40
onTransact() code: 2
greet() called with: Android Developer
greet() result: Hello, Android Developer! from Binder Service
GREET transaction completed, result: Hello, Android Developer! from Binder Service
onTransact() code: 3
getVersion() called
getVersion() result: 1
GET_VERSION transaction completed, version: 1
4. 高级 Binder 特性
4.1 带死亡通知的 Binder 服务
DeathRecipientService.cpp
cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <utils/String8.h>
#define LOG_TAG "DeathRecipientService"
using namespace android;
class DeathRecipientService : public BBinder {
private:
class DeathRecipient : public IBinder::DeathRecipient {
public:
DeathRecipient(DeathRecipientService* service) : mService(service) {}
virtual void binderDied(const wp<IBinder>& who) {
ALOGD("Client died: %p", who.unsafe_get());
if (mService) {
mService->handleClientDeath(who);
}
}
private:
DeathRecipientService* mService;
};
sp<DeathRecipient> mDeathRecipient;
int mClientCount;
public:
DeathRecipientService() : mClientCount(0) {
ALOGD("DeathRecipientService created");
mDeathRecipient = new DeathRecipient(this);
}
virtual ~DeathRecipientService() {
ALOGD("DeathRecipientService destroyed");
}
virtual status_t onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags) {
ALOGD("onTransact code: %u, calling PID: %d", code, IPCThreadState::self()->getCallingPid());
switch (code) {
case IBinder::FIRST_CALL_TRANSACTION: {
// 注册死亡通知
sp<IBinder> binder = data.readStrongBinder();
if (binder != nullptr) {
status_t status = binder->linkToDeath(mDeathRecipient);
if (status == NO_ERROR) {
mClientCount++;
ALOGD("Registered death recipient for client, total clients: %d", mClientCount);
}
}
String8 response = String8::format("Hello from DeathRecipientService! Clients: %d", mClientCount);
reply->writeString8(response);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
void handleClientDeath(const wp<IBinder>& who) {
ALOGD("Handling client death, removing from tracking");
mClientCount--;
ALOGD("Remaining clients: %d", mClientCount);
}
};
int main() {
ALOGD("=== Death Recipient Service Starting ===");
sp<ProcessState> proc(ProcessState::self());
proc->startThreadPool();
sp<DeathRecipientService> service = new DeathRecipientService();
status_t status = defaultServiceManager()->addService(
String16("death_recipient_service"), service);
if (status != NO_ERROR) {
ALOGE("Failed to register death_recipient_service");
return -1;
}
ALOGD("Death Recipient Service registered successfully");
IPCThreadState::self()->joinThreadPool();
return 0;
}
4.2 异步 Binder 调用
AsyncBinderService.cpp
cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <utils/Looper.h>
#include <utils/Thread.h>
#include <utils/Timers.h>
#define LOG_TAG "AsyncBinderService"
using namespace android;
class AsyncBinderService : public BBinder {
private:
class AsyncTask : public Thread {
private:
sp<IBinder> mCallback;
int mTaskId;
nsecs_t mStartTime;
public:
AsyncTask(const sp<IBinder>& callback, int taskId)
: mCallback(callback), mTaskId(taskId), mStartTime(systemTime()) {}
virtual bool threadLoop() {
ALOGD("AsyncTask %d started", mTaskId);
// 模拟长时间运行的任务
for (int i = 0; i <= 100; i += 20) {
usleep(200000); // 200ms
// 发送进度更新
if (mCallback != nullptr) {
Parcel data, reply;
data.writeInt32(mTaskId);
data.writeInt32(i); // 进度百分比
mCallback->transact(IBinder::FIRST_CALL_TRANSACTION + 1, data, &reply);
}
}
nsecs_t duration = (systemTime() - mStartTime) / 1000000; // 转换为毫秒
ALOGD("AsyncTask %d completed in %lld ms", mTaskId, (long long)duration);
// 发送完成通知
if (mCallback != nullptr) {
Parcel data, reply;
data.writeInt32(mTaskId);
data.writeString16(String16("Task completed successfully"));
mCallback->transact(IBinder::FIRST_CALL_TRANSACTION + 2, data, &reply);
}
return false; // 不重复执行
}
};
int mNextTaskId;
public:
AsyncBinderService() : mNextTaskId(1) {
ALOGD("AsyncBinderService created");
}
virtual ~AsyncBinderService() {
ALOGD("AsyncBinderService destroyed");
}
virtual status_t onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags) {
ALOGD("onTransact code: %u", code);
switch (code) {
case IBinder::FIRST_CALL_TRANSACTION: {
// 启动异步任务
sp<IBinder> callback = data.readStrongBinder();
int taskId = mNextTaskId++;
sp<AsyncTask> task = new AsyncTask(callback, taskId);
task->run("AsyncBinderTask");
reply->writeInt32(taskId);
ALOGD("Started async task %d", taskId);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
};
int main() {
ALOGD("=== Async Binder Service Starting ===");
sp<ProcessState> proc(ProcessState::self());
proc->startThreadPool();
sp<AsyncBinderService> service = new AsyncBinderService();
status_t status = defaultServiceManager()->addService(
String16("async_binder_service"), service);
if (status != NO_ERROR) {
ALOGE("Failed to register async_binder_service");
return -1;
}
ALOGD("Async Binder Service registered successfully");
IPCThreadState::self()->joinThreadPool();
return 0;
}
5. Binder 性能测试
5.1 Binder 调用性能测试
BinderBenchmark.cpp
cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <utils/Timers.h>
#include <utils/String8.h>
#define LOG_TAG "BinderBenchmark"
#define ITERATIONS 10000
using namespace android;
class BinderBenchmark {
private:
sp<IBinderDemoService> mService;
public:
bool connect() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("binder_demo_service"));
mService = interface_cast<IBinderDemoService>(binder);
return mService != nullptr;
}
void benchmarkAdd() {
if (mService == nullptr) return;
ALOGD("=== Benchmarking add() ===");
nsecs_t startTime = systemTime();
for (int i = 0; i < ITERATIONS; i++) {
mService->add(i, i + 1);
}
nsecs_t endTime = systemTime();
nsecs_t duration = endTime - startTime;
double avgTime = (double)duration / ITERATIONS / 1000.0; // 微秒
ALOGD("Add benchmark results:");
ALOGD(" Iterations: %d", ITERATIONS);
ALOGD(" Total time: %.2f ms", duration / 1000000.0);
ALOGD(" Average time: %.2f us per call", avgTime);
ALOGD(" Calls per second: %.0f", 1000000.0 / avgTime);
}
void benchmarkGreet() {
if (mService == nullptr) return;
ALOGD("=== Benchmarking greet() ===");
nsecs_t startTime = systemTime();
for (int i = 0; i < ITERATIONS; i++) {
String8 name = String8::format("User%d", i);
mService->greet(name);
}
nsecs_t endTime = systemTime();
nsecs_t duration = endTime - startTime;
double avgTime = (double)duration / ITERATIONS / 1000.0;
ALOGD("Greet benchmark results:");
ALOGD(" Iterations: %d", ITERATIONS);
ALOGD(" Total time: %.2f ms", duration / 1000000.0);
ALOGD(" Average time: %.2f us per call", avgTime);
ALOGD(" Calls per second: %.0f", 1000000.0 / avgTime);
}
};
int main() {
ALOGD("=== Binder Benchmark Starting ===");
sp<ProcessState> proc(ProcessState::self());
BinderBenchmark benchmark;
if (!benchmark.connect()) {
ALOGE("Failed to connect to service");
return -1;
}
ALOGD("Running benchmarks...");
benchmark.benchmarkAdd();
usleep(100000); // 100ms 休息
benchmark.benchmarkGreet();
ALOGD("=== Binder Benchmark Completed ===");
return 0;
}
性能测试结果:
=== Binder Benchmark Starting ===
Running benchmarks...
=== Benchmarking add() ===
Add benchmark results:
Iterations: 10000
Total time: 1250.45 ms
Average time: 125.05 us per call
Calls per second: 7997
=== Benchmarking greet() ===
Greet benchmark results:
Iterations: 10000
Total time: 1850.67 ms
Average time: 185.07 us per call
Calls per second: 5403
=== Binder Benchmark Completed ===
6. Binder 最佳实践
6.1 错误处理模式
cpp
status_t result = service->someMethod();
switch (result) {
case NO_ERROR:
// 成功处理
break;
case UNKNOWN_ERROR:
ALOGE("Unknown error occurred");
break;
case NO_MEMORY:
ALOGE("Out of memory");
break;
case INVALID_OPERATION:
ALOGE("Invalid operation");
break;
case BAD_VALUE:
ALOGE("Bad value provided");
break;
case BAD_INDEX:
ALOGE("Bad index");
break;
case BAD_TYPE:
ALOGE("Bad type");
break;
case NAME_NOT_FOUND:
ALOGE("Name not found");
break;
case PERMISSION_DENIED:
ALOGE("Permission denied");
break;
case NO_INIT:
ALOGE("Not initialized");
break;
case ALREADY_EXISTS:
ALOGE("Already exists");
break;
case DEAD_OBJECT:
ALOGE("Dead object - service died");
// 重新连接服务
reconnectService();
break;
default:
ALOGE("Unknown status: %d", result);
break;
}
6.2 内存管理最佳实践
cpp
class SafeBinderClient {
private:
mutable Mutex mLock;
sp<IBinderDemoService> mService;
sp<IBinderDemoService> getService() const {
Mutex::Autolock lock(mLock);
if (mService == nullptr) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("binder_demo_service"));
if (binder != nullptr) {
mService = interface_cast<IBinderDemoService>(binder);
// 设置死亡通知
binder->linkToDeath(new DeathRecipient(this));
}
}
return mService;
}
class DeathRecipient : public IBinder::DeathRecipient {
private:
wp<SafeBinderClient> mClient;
public:
DeathRecipient(SafeBinderClient* client) : mClient(client) {}
virtual void binderDied(const wp<IBinder>& who) {
ALOGD("Service died, cleaning up...");
if (SafeBinderClient* client = mClient.promote()) {
client->serviceDied();
}
}
};
void serviceDied() {
Mutex::Autolock lock(mLock);
mService = nullptr;
ALOGD("Service reference cleared due to death");
}
public:
status_t safeAdd(int32_t a, int32_t b, int32_t* result) {
sp<IBinderDemoService> service = getService();
if (service == nullptr) {
ALOGE("Service not available");
return DEAD_OBJECT;
}
try {
*result = service->add(a, b);
return NO_ERROR;
} catch (...) {
ALOGE("Exception in binder call");
serviceDied();
return UNKNOWN_ERROR;
}
}
};
7. 总结
通过以上 C/C++ 层的 Binder 实例,我们深入理解了:
- Binder 服务创建 :继承
BBinder或BnInterface实现服务 - 事务处理 :在
onTransact()中处理客户端请求 - 服务注册 :使用
defaultServiceManager()->addService() - 客户端连接 :使用
defaultServiceManager()->getService() - 接口转换 :使用
interface_cast<>将 IBinder 转换为具体接口 - 高级特性:死亡通知、异步调用、性能测试
- 错误处理:完善的错误码处理和异常恢复机制
这些实例展示了 Binder 在 Android 系统底层的工作原理,是理解 Android 系统架构和进行系统级开发的重要基础。