C++実現のbinder通信ウィジェット

4660 ワード

今日ネット上でC++でbinder通信を実現した人の小さな例を見ましたが、完全なdemoは提供されず、自分で整理して、本体で運行することができます.基本アーキテクチャはすべて同じで、コードは分析しないで、またbinderのメカニズムを分析しなければならなくて、どうせそれを1つのテンプレートとして使うことができて、関数を増加してあるいは修正して、つまりITestの中でvirtual関数を増加して、それぞれbp、bn、class Test端で実現して、そしてonTransactの中でcase分岐を増加して、十分に簡単でしょう、コードは以下の通りです:
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)