1 概述
大家都知道在Android下的IPC機制是Binder,它可以實現兩個進程之間的通信。有關Binder的介紹網上太多,這裡就不費話,OK,還是進入這篇文章的主題,即教你如何創建一個連接到Binder上的服務.並且這個示例中的源代碼是保證可以原樣編譯通過的.
在開始之前,我們首先來簡單介紹一下我們即將制作的服務ExampleServer, 這個示例服務由主程序加上一個libExample.so文件組成,libExample.so用來實現對Client端實現的接口,而主程序就是用來啟動這個服務的.費話不說了,下面進入正題.
2 步驟
第1步:生成ExampleService.so文件
1: 在framework/base目錄下新建一個目錄,用來保存libExample.so的源碼
- $cd framework/base/
- $mkdir ExampleService
進入此目錄:
- $cd ExampleService
新建3個文件:ExampleService.h ,ExampleService.cpp,Android.mk
其中ExampleService.h文件的內容如下:
- // 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
ExampleService.cpp文件的內容如下:
- // 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
Android.mk文件的內容如下:
- # 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_MODULE_TAGS := optional
- LOCAL_PRELINK_MODULE := false
- LOCAL_MODULE := libExample
-
- include $(BUILD_SHARED_LIBRARY)