Android Binder实战开发指南之Native层使用Java层Binder服务
Android Binder实战开发指南目录:
Android Binder实战开发指南Native层获取Process进程名和调用者进程名
Android Binder实战开发指南之Java层直接调用Native Binder Service
Android Binder开发实战指南之创建Native Binder Service
Android Binder实战开发指南之Native层使用Java层Binder服务
Android Binder实战开发指南之创建Java层Binder系统服务
承接上一篇 Android Binder实战开发指南之创建Java层Binder系统服务,前面主要介绍了在Java的世界里面怎么通过Binder进行PIC跨进程调用,那么本篇将介绍Native层怎么通过C++使用上一篇文章中实现的Binder服务。
实现步骤详解
- 获取远程BinderFunManager服务端代理
//获取系统服务BinderFunManager代理
sp<IBinder> getBinderFunService()
{
sp<IServiceManager> sm = defaultServiceManager();
return sm->getService(String16("BinderFunManager"));
}
- 跨进程调用
static String16 mydescriptor = String16("com.xxx.binderapifun.server.BinderFunManager");
data.writeInterfaceToken(mydescriptor);
static String16 str = String16("I am client from Native call");
data.writeString16(str);
binderFun->transact(TRANSAVTION_FUN, data, &reply, 0);
int result = reply.readInt32();
LOGE(TAG,"transact result : %d\n", result);
size_t datasize = reply.dataSize();
const uint8_t *data = reply.data();
for (int i = 0;i<datasize ;i++) {
LOGE(TAG,"Client data[%d] = %x",i,data[i]);
}
这样一次跨进程调用就实现了,是不是很简单。下面看看具体的调用结果
10-22 13:44:01.350 23625 23638 D BinderApiFun: FUN : I am client from Native call
10-22 13:44:01.352 25131 25131 E NativeClient: transact result : 0
10-22 13:44:01.352 25131 25131 E NativeClient: Client data[0] = 0
10-22 13:44:01.352 25131 25131 E NativeClient: Client data[1] = 0
10-22 13:44:01.352 25131 25131 E NativeClient: Client data[2] = 0
10-22 13:44:01.352 25131 25131 E NativeClient: Client data[3] = 0
具体实现代码如下
#include <pthread.h>
#include <sys/file.h>//flock's head
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <android/log.h>
#include <errno.h>
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <private/binder/binder_module.h>
#include <string.h>
#include <cutils/properties.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <stdarg.h>
#include <stdlib.h>
using namespace android;
#define LOGE(TAG,...) if(1) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__);
sp<IBinder> binderFun = NULL;//BinderFunManager的binder客户端
#define TRANSAVTION_FUN 1
#ifndef NULL
#define NULL (void*)0
#endif
#define TAG "NativeClient"
//获取系统服务BinderFunManager代理
sp<IBinder> getBinderFunService()
{
sp<IServiceManager> sm = defaultServiceManager();
return sm->getService(String16("BinderFunManager"));
}
extern "C" {
int main(void)
{
binderFun = getBinderFunService();
Parcel data,reply;
if(binderFun != NULL)
{
static String16 mydescriptor = String16("com.xxx.binderapifun.server.BinderFunManager");
data.writeInterfaceToken(mydescriptor);
static String16 str = String16("I am client from Native call");
data.writeString16(str);
binderFun->transact(TRANSAVTION_FUN, data, &reply, 0);
int result = reply.readInt32();
LOGE(TAG,"transact result : %d\n", result);
size_t datasize = reply.dataSize();
const uint8_t *data = reply.data();
for (int i = 0;i<datasize ;i++) {
LOGE(TAG,"Client data[%d] = %x",i,data[i]);
}
}else{
LOGE(TAG,"BinderFunManager service not exist\n");
}
return 0;
}
}
最后附上完整的代码连接Binder实战大荟萃源码,由于原来牵涉到公司相关信息所以其中的xxx替换了,具体参见源码比较好!