Android系统进程间通讯之Binder机制(二)
Android系统进程间通讯之Binder机制(二)
----实践篇
首先我们来看一张图,binder机制的层次模型:
如果想要实现Binder机制实现进程间的通讯,从理论篇中总结下来需要有一下几步:
(1)第一步,需要为这个接口定义一个继承自IInterface的接口类,假设叫做IExampleService。
(2)第二步,需要定义两个binder类,其中一个是代理类BpExampleService,需继承自
BpInterface,作为Server;另一个是实现类BnExampleService,需继承自BnInterface作为Client。
(3)第三步,定义BnExampleService和BpExampleService的子类,在其中真正实现接口所提供的各个函数。
(4)第四步,实现Server的启动注册,实现Client对Server的获取。
(5)第五步,通讯的实现。
下面,就这五步为基础,实现Binder的机制(以Example为例):
1. 定义IExampleServer的接口类:
Class IExampleService::public IInterface{
public:
DECLARE_META_INTERFACE (ExampleService);
//在此定义所需要定义的函数接口
virtual String6 *functionOne(const String6 *name) = 0;
//…………
};
注意:
1.1、宏定义: DECLARE_META_INTERFACE(ExampleService)。这个宏定义必须要有,其中封装了实现binder所需要的一些类成员变量和成员函数通过这些成员函数可以为一个binder实现创建proxy。这个宏定义在问价frameworks\base\include \utils\IInterface.h里,这个宏定义的参数必须是接口类的名称去除字母I后剩下的部分。
1.2、这里有时候会同时定义一个处理崩溃处理:
class DeathNotifier: public IBinder::DeathRecipient
{
public:
DeathNotifier() {
}
virtual void binderDied(const wp<IBinder>& who); //
};
void DeathNotifier::binderDied(const wp<IBinder>& who) {
//添加相应处理(Server:重新注册;Client:重新获取Server)
}
2. 定义BpExampleService类:
enum {
firstFunction = IBinder::FIRST_CALL_TRANSACTION,
secondFunction,
//……几个功能接口就定义几个枚举
};
class Bp ExampleService : public BpInterface<I ExampleService >
{
public:
BpAExampleService (const sp<IBinder>& impl)
: BpInterface<I ExampleService >(impl)
{
}
virtual String6 *functionOne(const String6 *name){
//实现具体数据的传递与获取返回值,在下面会有具体介绍
}
};
IMPLEMENT_META_INTERFACE(ExampleService, "android.myservice.ExampleService")
注:这行代码调用了一个宏定义IMPLEMENT_META_INTERFACE()。这个宏定义与前面提到过的 DECLARE_META_INTERFACE()相呼应。看名字就知道,IMPLEMENT_META_INTERFACE()宏是对 DECLARE_META_INTERFACE()所定义的成员函数的具体实现。这个宏的第一个参数与DECLARE_META_INTERFACE() 的参数需完全一样,第二参数是接口的描述字符串,描述字符串不重要,重要的是宏里面定义的一个静态成员函数 asInterface()。BpExampleService的类实例是在IExampleServer的静态成员函数 asInterface()中创建的,在IInterface.h中定义了一个内联函数interface_cast(),对这个成员函数进行了封装。通过看代码容易知道,BpExampleService的构造函数的参数是通过interface_cast()的参数传进来的。
3. 定义BnExampleService类:
enum {
firstFunction = IBinder::FIRST_CALL_TRANSACTION,
secondFunction,
//……几个功能接口就定义几个枚举,跟上面的对应
};
class BnExampleService: public BnInterface<IExampleService> {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
};
IMPLEMENT_META_INTERFACE(ExampleService, "android.myservice.ExampleService")
status_t BnExampleService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case firstFunction: {
CHECK_INTERFACE(IExampleService, data, reply);
//读取传过来的数据并做相应的处理
}
break;
case secondFunction: {
CHECK_INTERFACE(IExampleService, data, reply);
//读取传过来的数据并做相应的处理
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
注:宏定义CHECK_INTERFACE(),这个宏定义的作用是检查接口的描述字符串。
4. Server(BnExampleService)的启动注册:
class ExampleService: public Bn ExampleService {
public:
// If service manager is not present, wait until service manager becomes present.
static void instantiate();
protected:
ExampleService ();
virtual ~ ExampleService ();
};
void ExampleService::instantiate() {
defaultServiceManager()->addService(String16("Example.Service"),
new ExampleService ());
}
注:ExampleService::instantiate()函数的调用执行便可实现Server的注册和启动。
5. Client(BpExampleService)获取Server:
//类的声明
sp<IExampleService> gExampleService;
sp<DeathNotifier> mDeathNotifier;
//自定义一个初始化获取server的函数
void getExampleSInit(){
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("Example.Service"));
if (binder != 0)
break;
LOGW("ExampleService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
gExampleService = interface_cast<IExampleService>(binder);
//以下步骤解释待定
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
}
6. 通讯实现(发送并获取返回):
Client的通讯实现主要是通过之前定义的:
virtual String6*functionOne(const String6 *name)函数实现的,在这就这个函数做详细的描述:
virtual String6 *functionOne(const String6 *name){
//定义发送的值和接收的值
Parcel data, reply;
data.writeInterfaceToken(IExampleService::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(firstFunction, data, &reply);
returm reply;
String16 nameReturn = reply. readString16();
return nameReturn;
}
调用方式是:
String16 name = String16(“World”);
String16 theAnswer = gExampleService-> functionOne (name);
流程正确的情况下打印出来会发现theAnswer为:Hello The Worls!
7. 通讯实现(接收处理并返回):
同样的,Server的通讯实现主要是通过之前重构定义的:status_t
BnExampleService::onTransact(uint32_t code, const Parcel&data,Parcel* reply, uint32_t flags)函数实现的,具体实现描述如下:
status_t BnExampleService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case firstFunction: {
CHECK_INTERFACE(IExampleService, data, reply);
//读取传过来的数据并做相应的处理
}
break;
case secondFunction: {
CHECK_INTERFACE(IExampleService, data, reply);
//读取传过来的数据并做相应的处理
String16 name16 = data.readString16();
if(name16 == String16(“World”)){
//处理……
reply->writeString16(String16(“Hello The World!”));
}
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
当Client传来数据的时候,会自动调用onTransact函数进行处理。
需要注意的是:不管是.write还是.read方法,其前后对应顺序需要一致,否则容易出错。
上一篇: 日志学习
推荐阅读
-
Binder进程间通信系统第二篇-----Binder驱动程序
-
Android系统进程间通讯之Binder机制(二)
-
进程间通信学习系列(二)——简单了解Binder机制
-
Android Binder 机制初步学习 笔记(三)—— Binder 进程通讯库简介
-
Binder进程间通讯机制笔记
-
Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
-
Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
-
Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
-
浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路
-
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析