Android Binder Mechanism (1)

Binder是Android系统中实现进程间通信的核心机制,其本质是一种Proxy模式的具体实现,就像COM,CORBA一样。

    Proxy模式的基本思想是客户端程序通过某种方式得到服务器端的代理对象,所有对服务器端的服务请求都发送给该代理对象,该代理对象负责同服务器端进行通信。从客户端的角度看,访问代理对象就如同访问其它本地对象一样;服务器代理对象则屏蔽了所有的进程间通信细节。

    本文计划给出一个具体的例子,然后以这个例子为基础,深入剖析一下Android系统的绑定机制。

    实例:新增加一个系统服务ExampleService,该服务可以接受一个整形参数,将其值加上100并返回。客户端应用程序使用此服务计算1+100的值。

    代码1: 系统服务ExampleService的具体实现

 

view plain copy to clipboard print ?
  1. // File: ExampleService.h  
  2. #ifndef ANDROID_EXAMPLE_SERVICE_H  
  3. #define ANDROID_EXAMPLE_SERVICE_H  
  4. #include <utils/threads.h>  
  5. #include <utils/RefBase.h>  
  6. #include <binder/IInterface.h>  
  7. #include <binder/BpBinder.h>  
  8. #include <binder/Parcel.h>  
  9.   
  10. namespace android {  
  11.     class ExampleService : public BBinder  
  12.     {  
  13.         mutable Mutex mLock;  
  14.         int32_t mNextConnId;  
  15.         public:  
  16.             static int instantiate();  
  17.             ExampleService();  
  18.             virtual ~ExampleService();  
  19.             virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);  
  20.     };  
  21. }; //namespace  
  22. #endif  

 

 

view plain copy to clipboard print ?
  1. // File: ExampleService.cpp  
  2. #include "ExampleService.h"  
  3. #include <binder/IServiceManager.h>  
  4. #include <binder/IPCThreadState.h>  
  5.   
  6. namespace android {  
  7.   
  8.     static struct sigaction oldact;  
  9.     static pthread_key_t sigbuskey;  
  10.       
  11.     int ExampleService::instantiate()  
  12.     {  
  13.         LOGE("ExampleService instantiate");  
  14.         // 调用ServiceManager的addService方法进行系统服务注册,这样客户端程序就可以通过ServiceManager获得此服务的代理对象,从而请求其提供的服务  
  15.         int r = defaultServiceManager()->addService(String16("byn.example"), new ExampleService());  
  16.         LOGE("ExampleService r = %d/n", r);  
  17.         return r;  
  18.     }  
  19.   
  20.     ExampleService::ExampleService()  
  21.     {   
  22.         LOGV("ExampleService created");  
  23.         mNextConnId = 1;  
  24.         pthread_key_create(&sigbuskey, NULL);  
  25.     }  
  26.   
  27.     ExampleService::~ExampleService()  
  28.     {  
  29.         pthread_key_delete(sigbuskey);  
  30.         LOGV("ExampleService destroyed");  
  31.     }  
  32.     // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数  
  33.     status_t ExampleService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  34.     {  
  35.         switch(code)  
  36.         {  
  37.             case 0: {  
  38.                 pid_t pid = data.readInt32();  
  39.                 int num   = data.readInt32();  
  40.                 num = num + 100;  
  41.                 reply->writeInt32(num);  
  42.                 return NO_ERROR;  
  43.                 }  
  44.                 break;  
  45.             default:  
  46.                 return BBinder::onTransact(code, data, reply, flags);  
  47.         }  
  48.     }  
  49. }; //namespace  

 

 

view plain copy to clipboard print ?
  1. # File: Android.mk  
  2. LOCAL_PATH:= $(call my-dir)  
  3. include $(CLEAR_VARS)  
  4. LOCAL_SRC_FILES:= /  
  5.     ExampleService.cpp  
  6. LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)  
  7. LOCAL_SHARED_LIBRARIES := /  
  8.     libutils libbinder  
  9. LOCAL_PRELINK_MODULE := false  
  10. LOCAL_MODULE := libExample  
  11.   
  12. include $(BUILD_SHARED_LIBRARY)  

 

    在/framework/android/src/frameworks/base下面新建一个文件夹ExampleService,将以上三个文件复制到该文件夹中。

    代码2:启动ExampleService的应用程序

 

view plain copy to clipboard print ?
  1. // File: ExampleServer.cpp  
  2. #include <sys/types.h>  
  3. #include <unistd.h>  
  4. #include <grp.h>  
  5. #include <binder/IPCThreadState.h>  
  6. #include <binder/ProcessState.h>  
  7. #include <binder/IServiceManager.h>  
  8. #include <utils/Log.h>  
  9. #include <private/android_filesystem_config.h>  
  10. #include "../ExampleService/ExampleService.h"  
  11.   
  12. using namespace android;  
  13.   
  14. int main(int argc, char** argv)  
  15. {  
  16.     sp<ProcessState> proc(ProcessState::self());  // 要想使用Binder机制,必须要创建一个ProcessState对象  
  17.     sp<IServiceManager> sm = defaultServiceManager();  
  18.     LOGI("ServiceManager: %p", sm.get());  
  19.     ExampleService::instantiate();  
  20.     ProcessState::self()->startThreadPool();  
  21.     IPCThreadState::self()->joinThreadPool();  
  22.     return 0;  
  23. }  

 

 

view plain copy to clipboard print ?
  1. # File: Android.mk  
  2. LOCAL_PATH:= $(call my-dir)  
  3. include $(CLEAR_VARS)  
  4. LOCAL_SRC_FILES:= /  
  5.     ExampleServer.cpp  
  6. LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)  
  7. LOCAL_SHARED_LIBRARIES := /  
  8.     libutils libbinder libExample  
  9. LOCAL_PRELINK_MODULE := false  
  10. LOCAL_MODULE := ExampleServer  
  11.   
  12. include $(BUILD_EXECUTABLE)  

 

    在/framework/android/src/frameworks/base下面新建一个文件夹ExampleServer,将以上两个文件复制到该文件夹中。

    代码3:使用ExampleService的客户端应用程序

 

view plain copy to clipboard print ?
  1. // File: Example.h  
  2. #ifndef ANDROID_BYN_EXAMPLE_H  
  3. #define ANDROID_BYN_EXAMPLE_H  
  4.   
  5. namespace android  
  6. {  
  7.     class Example {  
  8.     public:  
  9.         void add100(int n);  
  10.         private:  
  11.         static const void getExampleService();  
  12.     };  
  13. }; //namespace   
  14. #endif // ANDROID_BYN_EXAMPLE_H  

 

 

view plain copy to clipboard print ?
  1. // File: Example.cpp  
  2. #include <binder/IServiceManager.h>  
  3. #include <binder/IPCThreadState.h>  
  4. #include "Example.h"  
  5.   
  6. namespace android  
  7. {  
  8.     sp<IBinder> binder;  
  9.     void Example::add100(int n)  
  10.     {  
  11.         getExampleService();  
  12.         Parcel data, reply;  
  13.         int answer;  
  14.           
  15.         data.writeInt32(getpid());  
  16.         data.writeInt32(n);  
  17.         LOGE("BpExampleService::create remote()->transact()/n");  
  18.         binder->transact(0, data, &reply);  
  19.         answer = reply.readInt32();  
  20.         printf("answner=%d/n", answer);      
  21.         return;  
  22.     }  
  23.   
  24.     const void Example::getExampleService()  
  25.     {  
  26.         sp<IServiceManager> sm = defaultServiceManager();  
  27.         binder = sm->getService(String16("byn.example"));  
  28.         LOGE("Example::getExampleService %p/n",sm.get());  
  29.         if (binder == 0) {  
  30.             LOGW("ExampleService not published, waiting...");  
  31.         return;  
  32.         }  
  33.     }  
  34. }; //namespace  
  35.   
  36. using namespace android;  
  37.   
  38. int main(int argc, char** argv)  
  39. {  
  40.     Example* p = new Example();  
  41.     p->add100(1);  
  42.     return 0;  
  43. }  

 

 

view plain copy to clipboard print ?
  1. # File: Example  
  2. LOCAL_PATH:= $(call my-dir)  
  3. include $(CLEAR_VARS)  
  4. LOCAL_SRC_FILES:= /  
  5.     Example.cpp  
  6. LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)  
  7. LOCAL_SHARED_LIBRARIES := /  
  8.     libutils libbinder libExample  
  9. LOCAL_PRELINK_MODULE := false  
  10. LOCAL_MODULE := Example  
  11.   
  12. include $(BUILD_EXECUTABLE)  

 

    在/framework/android/src/frameworks/base下面新建一个文件夹Example,将以上三个文件复制到该文件夹中。

    Build整个Android系统,这里一共会在系统中生成三个文件,分别是

    /system/lib/libExample.so

    /system/bin/ExampleServer

    /system/bin/Example

    然后启动我们新添加的ExampleService系统服务,并启动客户端程序验证运行结果。

    $> adb shell

    # cd /system/bin

    # ./ExampleServer &

    # ./Example

    answer=101

    在接下来的几篇文章中,我们会以这个例子为基础,深入分析一下Android系统中Binder机制的各个部分。

    参考文献:

    1. 云中漫步博客:http://my.unix-center.net/~Simon_fu/

    2. 如何撰写自己的第一个核心服务--高焕堂:http://www.android1.net/Topic.aspx?BoardID=21&TopicID=990

你可能感兴趣的:(android,Module,service,jni,Build,include)