该小节,主要是把上小节我们编写的代码,进行修改,然后编译进入系统
IHelloService.h
/* ²Î¿¼: frameworks\av\include\media\IMediaPlayerService.h */
#ifndef ANDROID_IHELLOERVICE_H
#define ANDROID_IHELLOERVICE_H
#include // for status_t
#include
#include
#include
#include
#include
#define HELLO_SVR_CMD_SAYHELLO 0
#define HELLO_SVR_CMD_SAYHELLO_TO 1
namespace android {
class IHelloService: public IInterface
{
public:
DECLARE_META_INTERFACE(HelloService);
virtual void sayhello(void) = 0;
virtual int sayhello_to(const char *name) = 0;
};
class BnHelloService: public BnInterface
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
virtual void sayhello(void);
virtual int sayhello_to(const char *name);
};
}
#endif
BnHelloService.cpp
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
#define LOG_TAG "HelloService"
#include "IHelloService.h"
namespace android {
status_t BnHelloService::onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
/* 解析数据,调用sayhello/sayhello_to */
switch (code) {
case HELLO_SVR_CMD_SAYHELLO: {
sayhello();
return NO_ERROR;
} break;
case HELLO_SVR_CMD_SAYHELLO_TO: {
/* 从data中取出参数 */
int32_t policy = data.readInt32();
String16 name16 = data.readString16();
String8 name8(name16);
int cnt = sayhello_to(name8.string());
/* 把返回值写入reply传回去 */
reply->writeInt32(cnt);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
void BnHelloService::sayhello(void)
{
static int cnt = 0;
ALOGI("say hello : %d\n", cnt++);
}
int BnHelloService::sayhello_to(const char *name)
{
static int cnt = 0;
ALOGI("say hello to %s : %d\n", name, cnt++);
return cnt;
}
}
BpHelloService.cpp
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
#include "IHelloService.h"
namespace android {
class BpHelloService: public BpInterface
{
public:
BpHelloService(const sp& impl)
: BpInterface(impl)
{
}
void sayhello(void)
{
/* 构造/发送数据 */
Parcel data, reply;
data.writeInt32(0);
remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);
}
int sayhello_to(const char *name)
{
/* 构造/发送数据 */
Parcel data, reply;
data.writeInt32(0);
data.writeString16(String16(name));
remote()->transact(HELLO_SVR_CMD_SAYHELLO_TO, data, &reply);
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(HelloService, "android.media.IHelloService");
}
test_server.cpp
/* 参考: frameworks\av\media\mediaserver\Main_mediaserver.cpp */
#define LOG_TAG "HelloService"
//#define LOG_NDEBUG 0
#include
#include
#include
#include
#include
#include
#include
#include
#include "IHelloService.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());
/* 循环体 */
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
test_client.cpp
#define LOG_TAG "HelloService"
//#define LOG_NDEBUG 0
#include
#include
#include
#include
#include
#include
#include
#include
#include "IHelloService.h"
using namespace android;
/* ./test_client hello
* ./test_client hello
*/
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);
}
return 0;
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
BnHelloService.cpp \
BpHelloService.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 \
test_client.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
liblog \
libbinder
LOCAL_MODULE:= test_client
LOCAL_32_BIT_ONLY := true
include $(BUILD_EXECUTABLE)
在APP_004_Binder_CPP_App文件夹中,编写完成以上文件之后,把APP_004_Binder_CPP_App文件夹拷贝到SDK/frameworks/testing(自己创建)目录下,然后执行mmm命令,烧写到内核
实验现象待开发板启动之后,执行
test_server &
logcat HelloService:* *:S &
test_client hello
可以看到类似: 01-18 12:33:39.707 1455 1456 I HelloService: say hello : 0 01-18 12:33:39.708 1461 1461 I HelloService: client call sayhello 打印信息,代表完成,也可以再执行: test_client hello 看到如下打印信息 01-18 12:34:39.877 1455 1456 I HelloService: say hello to 123 : 0 01-18 12:34:39.877 1462 1462 I HelloService: client call sayhello_to, cnt = 1
下小节我们将对该些程序进行详细的分析。