Android Binder的使用和设计[android native serivce]

1.Service的启动:

int main(int argc, char** argv) {
	sp <ProcessState> proc(ProcessState::self());
	PartitionService::instantiate();
	ProcessState::self()->startThreadPool();
	IPCThreadState::self()->joinThreadPool();
	return 0;
}

2.客户端的定义和实现:

namespace android {


class PartitionClient: public RefBase {
public:
 static const sp<IPartition> & getPartitionService();
        //添加接口。。。
     int File_Open(char * fileName);
     int File_Read(int fd,char * readBuf,int length);
     int File_Write(int fd,char * writeBuf,int length);
     int File_Close(int fd);
private:
 static sp<IPartition> mPartitionService;
};


namespace android {

sp<IPartition> PartitionClient::mPartitionService;
const sp<IPartition>& PartitionClient::getPartitionService() {

	if (mPartitionService.get() == 0) {
		sp < IServiceManager > sm = defaultServiceManager();
		sp < IBinder > binder;

		do {
			binder = sm->getService(String16("Partition"));
			if (binder != 0) {
				LOGI("Partition client get\n");
				break;
			}
			LOGE("Partition client is inavailable\n");
			usleep(500000);
		} while (true);
		mPartitionService = interface_cast<IPartition> (binder);
	}
	LOGE("Partition client getPartitionService  out.\n");
	return mPartitionService;
}

int PartitionClient::File_Open(char *name) {	
	sp<IPartition> ps = getPartitionService();
	int ret = -1;
	if (ps != 0) {
		ret = ps->File_open(name);
	}
	return ret;
}//其余方法省。。
};
3.Binder的接口定义:
namespace android {

class IPartition: public IInterface {
public:
 DECLARE_META_INTERFACE(Partition);
   virtual  int File_Open(char * fileName)=0;
   virtual  int File_Read(int fd,char * readBuf,int length)=0;
   virtual  int File_Write(int fd,char * writeBuf,int length)=0;
   virtual  int File_Close(int fd)=0;
};
class BnPartition: public BnInterface<IPartition> {
public:
 virtual status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags= 0 );
};
}; 

4.Binder的实现:

#include "IPartition.h"

namespace android {

enum {
	FILE_OPEN = IBinder::FIRST_CALL_TRANSACTION,
	FILE_READ,
	FILE_WRITE,
	FILE_CLOSE,
};

class BpPartition: public BpInterface<IPartition> {
public:
	BpPartition(const sp<IBinder>& impl) :
		BpInterface<IPartition> (impl) {
	}
	virtual int Porting_Flash_Open(char * name) {
		Parcel data, reply;
		data.writeInterfaceToken(IPartition::getInterfaceDescriptor());
		data.writeCString(name);
		remote()->transact(FILE_OPEN, data, &reply);
		return reply.readInt32();
	}
	virtual int Porting_Flash_Read(int fd,char *readBuf,int length) {
		Parcel data, reply;
		data.writeInterfaceToken(IPartition::getInterfaceDescriptor());
		data.writeInt32(fd);		
		data.writeInt32(length);
		remote()->transact(FILE_READ, data, &reply);
		int ret = reply.readInt32();
		if (ret > 0) {
			const char *result = (const char *)reply.readInplace(ret);
			memcpy((char *) readBuf, result, ret);
		} else {
			memset(readBuf, 0, length);
		}
		return ret;
	}

	virtual int Porting_Flash_Write(int fd, char *writeBuf, int length) {
		Parcel data, reply;
		data.writeInterfaceToken(IPartition::getInterfaceDescriptor());
		data.writeInt32(fd);
		data.writeInt32(length);
		data.write((const char *) *writeBuf, length);		
		remote()->transact(FILE_WRITE, data, &reply);
		return reply.readInt32();
	}
	
	virtual int Porting_Flash_Close(int fd) {
		Parcel data, reply;
		data.writeInterfaceToken(IPartition::getInterfaceDescriptor());
		data.writeInt32(fd);
		remote()->transact(FILE_CLOSE, data, &reply);
		return reply.readInt32();
	}
};

IMPLEMENT_META_INTERFACE(Partition, "android.os.Partition");//liusl

status_t BnPartition::onTransact(uint32_t code, const Parcel& data,
		Parcel* reply, uint32_t flags) {
	switch (code) {
	case FILE_OPEN: {
		CHECK_INTERFACE(IPartition, data, reply);
		char *pName;
		int ret;
		pName = (char *) data.readCString();
		ret = File_Open(pName);
		reply->writeInt32(ret);
		return NO_ERROR;
	}
		break;

	case FILE_READ: {
		CHECK_INTERFACE(IPartition, data, reply);
		int fd;		
		char *pBuf;
		int length;
		int ret;
		fd = data.readInt32();		
		length = data.readInt32();
		pBuf = (char*) malloc(sizeof(char) * length);
		if (pBuf == NULL) {
			ret = -1;
			reply->writeInt32(ret);
			LOGI("onTransact File_Read malloc result failed.\n");
			goto ERR_EXIT;
		}
		ret = File_Read(fd,  pBuf, length);
		reply->writeInt32(ret);
		if(ret >0){
			reply->write((char *) pBuf, ret);			
		}
		free(pBuf);
		pBuf = NULL;
		ERR_EXIT:
		LOGI("onTransact File_Read ,ret =%d out\n",  (int)ret);
		return NO_ERROR;
	}
		break;

	case FILE_WRITE: {		
		CHECK_INTERFACE(IPartition, data, reply);
		int fd;		
		const char *pBuf;
		int length;
		int ret;
		fd = data.readInt32();
		length = data.readInt32();
		pBuf = (const char *) data.readInplace(length);
		ret = File_Write(fd,(char *) pBuf, length);
		reply->writeInt32(ret);
		return NO_ERROR;
	}
		break;
	case FILE_CLOSE: {
		CHECK_INTERFACE(IPartition, data, reply);
		int fd;
		int ret;
		fd = data.readInt32();
		ret = Porting_Flash_Close(fd);
		reply->writeInt32(ret);
		return NO_ERROR;
	}
		break;
	default:
		return BBinder::onTransact(code, data, reply, flags);
	}
}
}
;
5.服务端的定义和实现;直接调用真正的实现方法。


namespace android {

class PartitionService: public BnPartition {
public:
     static void instantiate();
     virtual int File_Open(char * fileName);
     virtual int File_Read(int fd,char * readBuf,int length);
     virtual int File_Write(int fd,char * writeBuf,int length);
     virtual int File_Close(int fd);

private:
 Mutex mExecuteLock;
};
}
;
 
namespace android {

void PartitionService::instantiate() {
	sp < IServiceManager > sm = defaultServiceManager();
	sm->addService(String16("Partition"), new PartitionService());
}
int PartitionService::int File_Open(char * name){
	Mutex::Autolock _l(mExecuteLock);	
	IPCThreadState* ipcState = IPCThreadState::self();
	signed int ret = -1;
	ret = File_Open_interface(name);
	return ret;
}
int PartitionService::File_Read(int fd,char *pBuf,int length) {
	Mutex::Autolock _l(mExecuteLock);
	IPCThreadState* ipcState = IPCThreadState::self();
	signed int ret = -1;
	ret = File_Read_interface(fd, pBuf, length);
	return ret;
}

int PartitionService::File_Write(int fd, char *pBuf, int length) {
	Mutex::Autolock _l(mExecuteLock);
	IPCThreadState* ipcState = IPCThreadState::self();
	signed int ret = -1;
	ret =  File_Write_interface( fd,pBuf,length);
	return ret;
}

int PartitionService::File_Close(int fd) {
	Mutex::Autolock _l(mExecuteLock);
	IPCThreadState* ipcState = IPCThreadState::self();
	long ret = -1;
	ret = File_Close_interface(fd);
	return ret;
}
};

6.Andorid MK的编写:


LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := eng

LOCAL_SRC_FILES:= \
	PartitionClient.cpp \
	IPartition.cpp

LOCAL_SHARED_LIBRARIES := \
	libutils \
	libcutils \
	libbinder 
		
LOCAL_MODULE := libPartitionClient
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := eng

LOCAL_SRC_FILES:= \
	PartitionService.cpp \
	底层实现.cpp
	
LOCAL_SHARED_LIBRARIES := \	
	libutils \
	liblog \
	libcutils \
	libbinder \
	libPartitionClient

LOCAL_MODULE := libPartitionService
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := eng
LOCAL_SRC_FILES:= \
	PartitionServer.cpp

LOCAL_SHARED_LIBRARIES := \
	libui \
	libutils \
	libcutils \
	libbinder \
	libPartitionService \
	libPartitionClient
	
LOCAL_MODULE := PartitionServer

include $(BUILD_EXECUTABLE)


7.注意事项:

  以上是对文件操作的一个Binder实现,很简单。但在实现过程中,第一次写C++ 代码,容易忽略namespace的使用,以及Parcel接口中对字符串的读写:

  在Parcal接口,对字符串的读写分为

   const char* Parcel::readCString()
   const char16_t* Parcel::readString16Inplace(size_t* outLen)

  若字符串中有0的情况下,readCString是会自动截取的,也就是会出现字符串丢失。write也是一样。

  

你可能感兴趣的:(android,service,native,Binder,Binder机制,Binder的使用)