欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-24 09:11:58
...

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


                                   ----实践篇


   

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

Android系统进程间通讯之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方法,其前后对应顺序需要一致,否则容易出错。