学习到这个我们对Binder系统以及非常的了解了,那么我们现在添加一个binder服务会不会非常的简单呢?
假设现在我们添加一个服务,server端涉及一个BnGoodbyeService,client涉及一个BpGoodbyeService,其中实现两个函数saygoodbye,saygoodbye_to。BpGoodbyeService与BpGoodbyeService对使用同一个接口IGoodbyService。
故我们需要编写IGoodbyService.h,BnGoodbyService.cpp与BpGoodbyService.cpp三个函数。由于他和之前的Hello服务十分相似,我们把之前的IHelloService.h,BnHelloService.cpp,BpHelloService.cpp拷贝一份,然后把文件名中的Goodby替换成Hello,在其基础上进行修改:
IGoodbyeService.h
/* ²Î¿¼: frameworks\av\include\media\IMediaPlayerService.h */
#ifndef ANDROID_IGOODBYEERVICE_H
#define ANDROID_IGOODBYEERVICE_H
#include // for status_t
#include
#include
#include
#include
#include
#define GOODBYE_SVR_CMD_SAYGOODBYE 0
#define GOODBYE_SVR_CMD_SAYGOODBYE_TO 1
namespace android {
class IGoodbyeService: public IInterface
{
public:
DECLARE_META_INTERFACE(GoodbyeService);
virtual void saygoodbye(void) = 0;
virtual int saygoodbye_to(const char *name) = 0;
};
class BnGoodbyeService: public BnInterface
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
virtual void saygoodbye(void);
virtual int saygoodbye_to(const char *name);
};
}
#endif
BnGoodbyeService.cpp
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
#define LOG_TAG "GoodbyeService"
#include "IGoodbyeService.h"
namespace android {
status_t BnGoodbyeService::onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
/* 解析数据,调用saygoodbye/saygoodbye_to */
switch (code) {
case GOODBYE_SVR_CMD_SAYGOODBYE: {
saygoodbye();
return NO_ERROR;
} break;
case GOODBYE_SVR_CMD_SAYGOODBYE_TO: {
/* 从data中取出参数 */
int32_t policy = data.readInt32();
String16 name16 = data.readString16();
String8 name8(name16);
int cnt = saygoodbye_to(name8.string());
/* 把返回值写入reply传回去 */
reply->writeInt32(cnt);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
void BnGoodbyeService::saygoodbye(void)
{
static int cnt = 0;
ALOGI("say goodbye : %d\n", cnt++);
}
int BnGoodbyeService::saygoodbye_to(const char *name)
{
static int cnt = 0;
ALOGI("say goodbye to %s : %d\n", name, cnt++);
return cnt;
}
}
BpGoodbyeService.cpp
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
#include "IGoodbyeService.h"
namespace android {
class BpGoodbyeService: public BpInterface
{
public:
BpGoodbyeService(const sp& impl)
: BpInterface(impl)
{
}
void saygoodbye(void)
{
/* 构造/发送数据 */
Parcel data, reply;
data.writeInt32(0);
remote()->transact(GOODBYE_SVR_CMD_SAYGOODBYE, data, &reply);
}
int saygoodbye_to(const char *name)
{
/* 构造/发送数据 */
Parcel data, reply;
data.writeInt32(0);
data.writeString16(String16(name));
remote()->transact(GOODBYE_SVR_CMD_SAYGOODBYE_TO, data, &reply);
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(GoodbyeService, "android.media.IGoodbyeService");
}
test_client.cpp
#define LOG_TAG "TestService"
//#define LOG_NDEBUG 0
#include
#include
#include
#include
#include
#include
#include
#include
#include "IHelloService.h"
#include "IGoodbyeService.h"
using namespace android;
/* ./test_client
* ./test_client
*/
int main(int argc, char **argv)
{
int cnt;
if (argc getService(String16("hello"));
if (binder == 0)
{
ALOGI("can't get hello service\n");
return -1;
}
/* service肯定是BpHelloServie指针 */
sp service =
interface_cast(binder);
/* 调用Service的函数 */
if (argc sayhello();
ALOGI("client call sayhello");
}
else {
cnt = service->sayhello_to(argv[2]);
ALOGI("client call sayhello_to, cnt = %d", cnt);
}
}
else
{
sp binder =
sm->getService(String16("goodbye"));
if (binder == 0)
{
ALOGI("can't get goodbye service\n");
return -1;
}
/* service肯定是BpGoodbyeServie指针 */
sp service =
interface_cast(binder);
/* 调用Service的函数 */
if (argc saygoodbye();
ALOGI("client call saygoodbye");
}
else {
cnt = service->saygoodbye_to(argv[2]);
ALOGI("client call saygoodbye_to, cnt = %d", cnt);
}
}
return 0;
}
test_server.cpp
/* 参考: frameworks\av\media\mediaserver\Main_mediaserver.cpp */
#define LOG_TAG "TestService"
//#define LOG_NDEBUG 0
#include
#include
#include
#include
#include
#include
#include
#include
#include "IHelloService.h"
#include "IGoodbyeService.h"
using namespace android;
int main(void)
{
/* addService */
/* while(1){ read data, 解析数据, 调用服务函数 } */
/* 打开驱动, mmap */
sp proc(ProcessState::self());
/* 获得BpServiceManager */
sp sm = defaultServiceManager();
sm->addService(String16("hello"), new BnHelloService());
sm->addService(String16("goodbye"), new BnGoodbyeService());
/* 循环体 */
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
BnHelloService.cpp \
BpHelloService.cpp \
BnGoodbyeService.cpp \
BpGoodbyeService.cpp \
test_server.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
liblog \
libbinder
LOCAL_MODULE:= test_server
LOCAL_32_BIT_ONLY := true
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
BpHelloService.cpp \
BpGoodbyeService.cpp \
test_client.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
liblog \
libbinder
LOCAL_MODULE:= test_client
LOCAL_32_BIT_ONLY := true
include $(BUILD_EXECUTABLE)
编写完成以上代码之后,使用mmm命令编译,然后烧写到系统,实验操作参考之前:05.Binder系统:第7课第2节_Binder系统_c++实现_编译测试