구체적인 예로 안드로이드 시스템의 귀속 메커니즘을 깊이 있게 분석하다

7066 단어
에서http://blog.csdn.net/bigapple88/article/details/6579732
Binder는 안드로이드 시스템에서 프로세스 간 통신을 실현하는 핵심 메커니즘으로 그 본질은 일종의 Proxy 모델의 구체적인 실현이다. 예를 들어COM,CORBA와 같다.
Proxy 모델의 기본 사상은 클라이언트 프로그램이 어떤 방식을 통해 서버 측의 프록시 대상을 얻어 모든 서버 측에 대한 서비스 요청을 이 프록시 대상에게 보내고 이 프록시 대상은 서버 측과 통신하는 것을 책임진다는 것이다.클라이언트의 측면에서 볼 때 액세스 에이전트 대상은 다른 로컬 대상을 방문하는 것과 같다.서버 프록시 대상은 모든 프로세스 간의 통신 세부 사항을 차단합니다.
본고는 구체적인 예를 제시한 다음에 이 예를 바탕으로 안드로이드 시스템의 귀속 메커니즘을 깊이 있게 분석할 계획이다.
예: 시스템 서비스 Example Service가 새로 추가되었습니다. 이 서비스는 성형 파라미터를 받아들여 그 값을 100으로 추가하고 되돌려줍니다.클라이언트 응용 프로그램은 이 서비스를 사용하여 1+100의 값을 계산합니다.
코드1: 시스템 서비스 Example 서비스의 구체적인 실현
// File: ExampleService.h
#ifndef ANDROID_EXAMPLE_SERVICE_H
#define ANDROID_EXAMPLE_SERVICE_H
#include <utils/threads.h>
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>

namespace android {
    class ExampleService : public BBinder
    {
        mutable Mutex mLock;
        int32_t mNextConnId;
        public:
            static int instantiate();
            ExampleService();
            virtual ~ExampleService();
            virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
	};
}; //namespace
#endif
// File: ExampleService.cpp
#include "ExampleService.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

namespace android {

    static struct sigaction oldact;
    static pthread_key_t sigbuskey;
    
    int ExampleService::instantiate()
    {
        LOGE("ExampleService instantiate");
        //  ServiceManager addService , ServiceManager , 
        int r = defaultServiceManager()->addService(String16("byn.example"), new ExampleService());
        LOGE("ExampleService r = %d/n", r);
        return r;
    }

    ExampleService::ExampleService()
    { 
        LOGV("ExampleService created");
        mNextConnId = 1;
        pthread_key_create(&sigbuskey, NULL);
    }

    ExampleService::~ExampleService()
    {
        pthread_key_delete(sigbuskey);
        LOGV("ExampleService destroyed");
    }
    //  BBinder , BBinder onTransact 。 Service , Service onTransact 
    status_t ExampleService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        switch(code)
        {
            case 0: {
                pid_t pid = data.readInt32();
                int num   = data.readInt32();
                num = num + 100;
                reply->writeInt32(num);
                return NO_ERROR;
                }
                break;
            default:
                return BBinder::onTransact(code, data, reply, flags);
        }
    }
}; //namespace
# File: Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
	ExampleService.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := /
	libutils libbinder
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libExample

include $(BUILD_SHARED_LIBRARY)

/framework/android/src/frameworks/base 아래에 새 폴더 Example Service를 만듭니다. 이 세 개의 파일을 이 폴더에 복사합니다.
코드 2: Example Service를 실행하는 응용 프로그램
// File: ExampleServer.cpp
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <private/android_filesystem_config.h>
#include "../ExampleService/ExampleService.h"

using namespace android;

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());	//  Binder , ProcessState 
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p", sm.get());
    ExampleService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return 0;
}
# File: Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
	ExampleServer.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := /
	libutils libbinder libExample
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := ExampleServer

include $(BUILD_EXECUTABLE)

/framework/android/src/frameworks/base 아래에 새 폴더 Example Server를 만들고 두 파일을 이 폴더로 복사합니다.
코드 3: Example Service를 사용하는 클라이언트 응용 프로그램
// File: Example.h
#ifndef ANDROID_BYN_EXAMPLE_H
#define ANDROID_BYN_EXAMPLE_H

namespace android
{
    class Example {
    public:
        void add100(int n);
        private:
        static const void getExampleService();
    };
}; //namespace 
#endif // ANDROID_BYN_EXAMPLE_H
// File: Example.cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "Example.h"

namespace android
{
    sp<IBinder> binder;
    void Example::add100(int n)
    {
        getExampleService();
        Parcel data, reply;
        int answer;
        
        data.writeInt32(getpid());
        data.writeInt32(n);
        LOGE("BpExampleService::create remote()->transact()/n");
        binder->transact(0, data, &reply);
        answer = reply.readInt32();
        printf("answner=%d/n", answer);    
        return;
    }

    const void Example::getExampleService()
    {
        sp<IServiceManager> sm = defaultServiceManager();
        binder = sm->getService(String16("byn.example"));
        LOGE("Example::getExampleService %p/n",sm.get());
        if (binder == 0) {
            LOGW("ExampleService not published, waiting...");
        return;
        }
    }
}; //namespace

using namespace android;

int main(int argc, char** argv)
{
    Example* p = new Example();
    p->add100(1);
    return 0;
}
# File: Example
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
	Example.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := /
	libutils libbinder libExample
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := Example

include $(BUILD_EXECUTABLE)

/framework/android/src/frameworks/base 아래에 새 폴더 Example을 만들고 세 개의 파일을 이 폴더로 복사합니다.
 
Build 전체 Android 시스템에는 각각 세 개의 파일이 생성됩니다.
   /system/lib/libExample.so
   /system/bin/ExampleServer
   /system/bin/Example
 
그리고 저희가 새로 추가한 Example 서비스 시스템 서비스를 시작하고 클라이언트 프로그램을 시작하여 실행 결과를 검증합니다.
    $> adb shell
    # cd/system/bin
    # ./ExampleServer &
    # ./Example
    answer=101
 
다음 몇 편의 글에서 우리는 이 예를 바탕으로 안드로이드 시스템의 Binder 메커니즘의 각 부분을 깊이 있게 분석할 것이다.
 
 
참조 자료:
    1. 클라우드 워킹 블로그:http://my.unix-center.net/~Simon_fu/
    2. 자신의 첫 번째 핵심 서비스인 고환당을 어떻게 작성하는가:http://www.android1.net/Topic.aspx?BoardID=21&TopicID=990

좋은 웹페이지 즐겨찾기