Binder通信是Android用的比较多的一种通信机制,它是一种client-server的通信结构。Binder通信具有以下特点:1、用驱动程序来推进进程间的通信;2、可以通过共享内存的方式来提供性能;3、 可以为进程请求分配每个进程的线程池;4、针对系统中的对象引入了引用计数和跨进程的对象引用映射;5、可以方便的进行进程同步调用。Binder方面的资料网上非常多,单对于初学者来学,有些资料有些深刻,所以先打算写一个最简单的Binder实例来开始对Binder的学习。
首先看看整个实例的目录:
Binder下面放的是启动Binder服务程序,Binderserver下面放的是Binder服务的server和client端,而Test下面放的是一个简单的测试Binder服务的测试程序。
先来看Binderserver下面的内容:
1、IBinderTest.h
#ifndef IBINDERTEST_H_
#define IBINDERTEST_H_
#include
#include
#include
#include
namespace android {
class Parcel;
class IBinderTest : public IInterface {
public:
DECLARE_META_INTERFACE(BinderTest);
virtual int32_t testCmd(uint32_t cmdId, uint32_t paramLen) = 0;
};
class BnBinderTest: public BnInterface {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
private:
bool checkPermission(const String16& permission);
};
}; // namespace android
#endif
这里主要实现了两个类,IBinderTest跟BnBinderTest,IBinderTest是BinderTest的基类。
在IBinderTest.h里面有个比较重要的宏,DECLARE_META_INTERFACE,该宏定义在:frameworks\base\include\binder\IInterface.h中
#define DECLARE_META_INTERFACE(INTERFACE) \
static const android::String16 descriptor; \
static android::sp asInterface( \
const android::sp& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
代入BinderTest后:
#define DECLARE_META_INTERFACE(BinderTest) \
static const android::String16 descriptor; \
static android::sp asInterface( \
const android::sp& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
IBinderTest(); \
virtual ~"IBinderTest();
DECLARE_META_INTERFACE封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy,这里主要是申明了asInterface这个函数,后面会说明这个函数的实现。
2、IBinderTest.cpp
IBinderTest.cpp主要是实现IBinderTest.h里面申明的一些函数:
#include
#include
#include
#include
#include "IBinderTest.h"
namespace android {
enum {
TEST_CMD = IBinder::FIRST_CALL_TRANSACTION,
};
class BpBinderTest : public BpInterface
{
public:
BpBinderTest(const sp& impl) :
BpInterface(impl) {
}
int32_t testCmd(uint32_t cmdId, uint32_t paramLen) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeInt32(cmdId);
data.writeInt32(paramLen);
remote()->transact(TEST_CMD, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(BinderTest, "android.hardware.fingerprint.IBinderTest");
status_t BnBinderTest::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
switch(code) {
case TEST_CMD: {
CHECK_INTERFACE(IBinderTest, data, reply);
int32_t cmdId = data.readInt32();
int32_t paramLen = data.readInt32();
// const uint8_t* param = static_cast(data.readInplace(paramLen));
ALOGV("%s, %s, %d", cmdId, paramLen);
const int32_t ret = testCmd(cmdId, paramLen);
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
bool BnBinderTest::checkPermission(const String16& permission) {
bool ret = true;
if (permission.size())
return true;
return ret;
}
}; // namespace android
这里主要看看IMPLEMENT_META_INTERFACE这个宏,跟DECLARE_META_INTERFACE一样,也定义在frameworks\base\include\binder\IInterface.h中:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp I##INTERFACE::asInterface( \
const android::sp& obj) \
{ \
android::sp intr; \
if (obj != NULL) { \
intr = static_cast( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
代入相应参数展开后:
#define IMPLEMENT_META_INTERFACE(BinderTest, "android.hardware.fingerprint.IBinderTest") \
const android::String16 IBinderTest::descriptor(“android.hardware.fingerprint.IBinderTest”);
const android::String16& \
IBinderTest::getInterfaceDescriptor() const { \
return IBinderTest::descriptor; \
} \
android::sp IBinderTest::asInterface( \
const android::sp& obj) \
{ \
android::sp intr; \
if (obj != NULL) { \
intr = static_cast( \
obj->queryLocalInterface( \
IBinderTest::descriptor).get()); \
if (intr == NULL) { \
intr = new BpBinderTest(obj); \
} \
} \
return intr; \
} \
IBinderTest::IBinderTest() { } \
IBinderTest::~IBinderTest() { } \
宏IMPLEMENT_META_INTERFACE主要是来实现asInterface,asInterface里面先调用queryLocalInterface,这个方法是IBinder定义的,默认实现是返回NULL,而在BBinder的子类BnInterface中,重载了该方法,返回this,而BpInterface并没有重载,使用IBinder的默认实现,返回NULL。而如果queryLocalInterface返回NULL,就构造一个BpXXXService返回,Client得到的正是这个BpXXXService。所以如果传进来的obj参数,是一个BBinder,就返回自身(这种情况应该是service和client在同一进程),如果是一个BpBinder,就new一个代理对象返回(这种情况应该是service和client在不同进程)。
3、BinderTest.h
#ifndef BINDERTEST_H_
#define BINDERTEST_H_
#include "IBinderTest.h"
namespace android {
class BinderTest : public BnBinderTest{
public:
static BinderTest* getInstance() {
if (sInstance == NULL) {
ALOGD("%s", __func__);
sInstance = new BinderTest();
}
return sInstance;
}
static void instantiate();
virtual int32_t testCmd(uint32_t cmdId, uint32_t paramLen);
private:
BinderTest();
virtual ~BinderTest();
void binderDied(const wp& who);
static BinderTest* sInstance;
};
} // namespace android
#endif
这个文件比较简单,主要就是定义了一个BinderTest类,然后实现定义一些类里面的方法,函数instantiate跟testCmd。
4、BinderTest.cpp:
#define LOG_TAG "BinderTest"
#include
#include
//#include
#include
#include "BinderTest.h"
namespace android {
BinderTest* BinderTest::sInstance = NULL;
BinderTest::BinderTest() {
ALOGD("BinderTeststarted (pid=%d)", getpid());
ALOGD("BinderTestend (pid=%d)", getpid());
}
BinderTest::~BinderTest() {
ALOGD("BinderTest started (pid=%d)", getpid());
}
void BinderTest::instantiate() {
ALOGD("Enter %s", __func__);
status_t st = defaultServiceManager()->addService(
String16("my.test.binder"), new BinderTest());
ALOGD("ServiceManager addService ret=%d", st);
ALOGD("Enter %s", __func__);
}
int32_t BinderTest::testCmd(uint32_t cmdId, uint32_t paramLen) {
ALOGD("cmdif = %d, paramLen = %d", cmdId, paramLen);
return 0;
}
void BinderTest::binderDied(const wp& who) {
ALOGD("binder died");
}
}
在instantiate函数里面,将BinderTest注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法。而testCmd函数只是做了简单的打印操作。
至此Binder服务的client跟server端都已经实现,下面就是如何启动我们定义的这个服务,我们可以在系统的system_init.cpp里面加载instantiate函数来启动该服务,也可以以单独的程序来启动,如下所示:
#include
#include
#include
#include
#include
#include
#include
#include "../fptestserver/BinderTest.h"
#define LOG_TAG "BinderTest"
using namespace android;
int main()
{
ALOGI("TestService Starting " LOG_TAG);
sp proc(ProcessState::self());
sp sm = defaultServiceManager();
BinderTest::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
ALOGI("TestService end " LOG_TAG);
return 0;
}
这里直接调用了BinderTest里面的instantiate函数来实现的。
下面看看测试程序:
#define LOG_TAG "TestBinserService"
#include
#include
#include
#include
#include
#include "../fptestserver/BinderTest.h"
#include "../fptestserver/IBinderTest.h"
using namespace android;
int main(int argc, char** argv)
{
int sum = 0;
const uint8_t* param;
ALOGE("main enter");
sp mTestBinserService;
if (mTestBinserService.get() == 0) {
sp sm = defaultServiceManager();
sp binder;
do {
ALOGE("binder enter");
binder = sm->getService(String16("my.test.binder"));
if (binder != 0) {
ALOGE("getService ok");
break;
}
ALOGE("getService fail");
usleep(500000); // 0.5 s
} while (true);
mTestBinserService = interface_cast (binder);
ALOGE("mTestBinserService");
ALOGE_IF(mTestBinserService == 0, "no ITestBinserService!?");
}
sum = mTestBinserService->testCmd(3, param,4);
ALOGI("sum = %d", sum);
return 0;
}
启动Binderserver服务:
E/TestBinserService( 3449): main enter
E/TestBinserService( 3449): binder enter
E/TestBinserService( 3449): getService ok
E/TestBinserService( 3449): mTestBinserService
D/BinderTest( 3440): cmdif = 3, paramLen = 4
I/TestBinserService( 3449): sum = 0