Android系统进程间通讯之Binder机制(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/laozhuxinlu/article/details/72331557

Android系统进程间通讯之Binder机制(二)


                                   ----实践篇


   

    首先我们来看一张图,binder机制的层次模型:


    如果想要实现Binder机制实现进程间的通讯,从理论篇中总结下来需要有一下几步:

    (1)第一步,需要为这个接口定义一个继承自IInterface的接口类,假设叫做IExampleService 
    (2)第二步,需要定义两个binder类,其中一个是代理类BpExampleService,需继承自

BpInterface,作为Server;另一个是实现类BnExampleService,需继承自BnInterface作为Client 
     (3)第三步,定义BnExampleServiceBpExampleService的子类,在其中真正实现接口所提供的各个函数。 
     (4)第四步,实现Server的启动注册,实现ClientServer的获取。

     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. ServerBnExampleService)的启动注册:

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. ClientBpExampleService)获取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方法,其前后对应顺序需要一致,否则容易出错。








猜你喜欢

转载自blog.csdn.net/laozhuxinlu/article/details/72331557