C++実現のbinder通信ウィジェット
4660 ワード
今日ネット上でC++でbinder通信を実現した人の小さな例を見ましたが、完全なdemoは提供されず、自分で整理して、本体で運行することができます.基本アーキテクチャはすべて同じで、コードは分析しないで、またbinderのメカニズムを分析しなければならなくて、どうせそれを1つのテンプレートとして使うことができて、関数を増加してあるいは修正して、つまりITestの中でvirtual関数を増加して、それぞれbp、bn、class Test端で実現して、そしてonTransactの中でcase分岐を増加して、十分に簡単でしょう、コードは以下の通りです:
binder_test.h:
binder_test_client.cpp:
binder_test_service.cpp:
Android.mk:
binder_test.h:
#ifndef __BINDER_TEST_H
#define __BINDER_TEST_H
#include <binder/Parcel.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <unistd.h>
#include <stdio.h>
#include <utils/misc.h>
#include <utils/Atomic.h>
#include <utils/Log.h>
namespace android
{
class ITest : public IInterface
{
public:
DECLARE_META_INTERFACE(Test);
virtual void getTest() = 0;
};
class BnTest: public BnInterface<ITest>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
class Test : public BnTest
{
public:
//Test(){ALOGE("got the service");};
//~Test();
virtual void getTest(){ALOGE("got the service");};
void print(){ALOGE("got the service");};
};
enum {
PRINT = IBinder::FIRST_CALL_TRANSACTION,
};
class BpTest : public BpInterface<ITest>
{
public:
BpTest(const sp<IBinder>& impl ):BpInterface<ITest>(impl)
{
}
virtual void getTest()
{
printf("in the get Test
");
Parcel data, reply;
data.writeInterfaceToken(ITest::getInterfaceDescriptor());
remote()->transact(PRINT, data, &reply);
printf("send Print %d
",reply.readInt32());
}
};
IMPLEMENT_META_INTERFACE(Test,"android.TestServer.ITest");
status_t BnTest::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code)
{
case PRINT:
{
printf("got the client msg
");
CHECK_INTERFACE(ITest, data, reply);
getTest();
reply->writeInt32(100);
return NO_ERROR;
}break;
default:break;
}
return NO_ERROR;
}
}// namespace android
#endif
binder_test_client.cpp:
#include "binder_test.h"
using namespace android;
int main(int argc, char *argv[])
{
sp<IBinder> binder;
sp<ProcessState> proc(ProcessState::self());
//get service manager
sp<IServiceManager> sm = defaultServiceManager();
do{
binder = sm->getService(String16("service.testmanager"));
if(binder != 0)
break;
sleep(1);
}while(true);
const sp<ITest>& bts = interface_cast<ITest>(binder);
ALOGE("bindertest client is starting.....");
bts->getTest();
return 0;
}
binder_test_service.cpp:
#include "binder_test.h"
using namespace android;
int main(int argc, char *argv[])
{
sp<ProcessState> proc(ProcessState::self());
//get service manager
sp<IServiceManager> sm = defaultServiceManager();
sm->addService(String16("service.testmanager"),new Test());
ALOGE("bindertest service is starting.....");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
binder_test_service.cpp
LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder
# FIXME The duplicate audioflinger is temporary
LOCAL_C_INCLUDES := binder_test.h
LOCAL_MODULE:= bindertestservice
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
binder_test_client.cpp
LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder
# FIXME The duplicate audioflinger is temporary
LOCAL_C_INCLUDES := binder_test.h
LOCAL_MODULE:= bindertestclient
include $(BUILD_EXECUTABLE)