Android Binder Mechanism (1)

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

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

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

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

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

  1. //File:ExampleService.h
  2. #ifndefANDROID_EXAMPLE_SERVICE_H
  3. #defineANDROID_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. namespaceandroid{
  10. classExampleService:publicBBinder
  11. {
  12. mutableMutexmLock;
  13. int32_tmNextConnId;
  14. public:
  15. staticintinstantiate();
  16. ExampleService();
  17. virtual~ExampleService();
  18. virtualstatus_tonTransact(uint32_t,constParcel&,Parcel*,uint32_t);
  19. };
  20. };//namespace
  21. #endif

  1. //File:ExampleService.cpp
  2. #include"ExampleService.h"
  3. #include<binder/IServiceManager.h>
  4. #include<binder/IPCThreadState.h>
  5. namespaceandroid{
  6. staticstructsigactionoldact;
  7. staticpthread_key_tsigbuskey;
  8. intExampleService::instantiate()
  9. {
  10. LOGE("ExampleServiceinstantiate");
  11. //调用ServiceManager的addService方法进行系统服务注册,这样客户端程序就可以通过ServiceManager获得此服务的代理对象,从而请求其提供的服务
  12. intr=defaultServiceManager()->addService(String16("byn.example"),newExampleService());
  13. LOGE("ExampleServicer=%d/n",r);
  14. returnr;
  15. }
  16. ExampleService::ExampleService()
  17. {
  18. LOGV("ExampleServicecreated");
  19. mNextConnId=1;
  20. pthread_key_create(&sigbuskey,NULL);
  21. }
  22. ExampleService::~ExampleService()
  23. {
  24. pthread_key_delete(sigbuskey);
  25. LOGV("ExampleServicedestroyed");
  26. }
  27. //每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数
  28. status_tExampleService::onTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  29. {
  30. switch(code)
  31. {
  32. case0:{
  33. pid_tpid=data.readInt32();
  34. intnum=data.readInt32();
  35. num=num+100;
  36. reply->writeInt32(num);
  37. returnNO_ERROR;
  38. }
  39. break;
  40. default:
  41. returnBBinder::onTransact(code,data,reply,flags);
  42. }
  43. }
  44. };//namespace

  1. #File:Android.mk
  2. LOCAL_PATH:=$(callmy-dir)
  3. include$(CLEAR_VARS)
  4. LOCAL_SRC_FILES:=/
  5. ExampleService.cpp
  6. LOCAL_C_INCLUDES:=$(JNI_H_INCLUDE)
  7. LOCAL_SHARED_LIBRARIES:=/
  8. libutilslibbinder
  9. LOCAL_PRELINK_MODULE:=false
  10. LOCAL_MODULE:=libExample
  11. include$(BUILD_SHARED_LIBRARY)

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

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

  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. usingnamespaceandroid;
  12. intmain(intargc,char**argv)
  13. {
  14. sp<ProcessState>proc(ProcessState::self());//要想使用Binder机制,必须要创建一个ProcessState对象
  15. sp<IServiceManager>sm=defaultServiceManager();
  16. LOGI("ServiceManager:%p",sm.get());
  17. ExampleService::instantiate();
  18. ProcessState::self()->startThreadPool();
  19. IPCThreadState::self()->joinThreadPool();
  20. return0;
  21. }

  1. #File:Android.mk
  2. LOCAL_PATH:=$(callmy-dir)
  3. include$(CLEAR_VARS)
  4. LOCAL_SRC_FILES:=/
  5. ExampleServer.cpp
  6. LOCAL_C_INCLUDES:=$(JNI_H_INCLUDE)
  7. LOCAL_SHARED_LIBRARIES:=/
  8. libutilslibbinderlibExample
  9. LOCAL_PRELINK_MODULE:=false
  10. LOCAL_MODULE:=ExampleServer
  11. include$(BUILD_EXECUTABLE)

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

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

  1. //File:Example.h
  2. #ifndefANDROID_BYN_EXAMPLE_H
  3. #defineANDROID_BYN_EXAMPLE_H
  4. namespaceandroid
  5. {
  6. classExample{
  7. public:
  8. voidadd100(intn);
  9. private:
  10. staticconstvoidgetExampleService();
  11. };
  12. };//namespace
  13. #endif//ANDROID_BYN_EXAMPLE_H

  1. //File:Example.cpp
  2. #include<binder/IServiceManager.h>
  3. #include<binder/IPCThreadState.h>
  4. #include"Example.h"
  5. namespaceandroid
  6. {
  7. sp<IBinder>binder;
  8. voidExample::add100(intn)
  9. {
  10. getExampleService();
  11. Parceldata,reply;
  12. intanswer;
  13. data.writeInt32(getpid());
  14. data.writeInt32(n);
  15. LOGE("BpExampleService::createremote()->transact()/n");
  16. binder->transact(0,data,&reply);
  17. answer=reply.readInt32();
  18. printf("answner=%d/n",answer);
  19. return;
  20. }
  21. constvoidExample::getExampleService()
  22. {
  23. sp<IServiceManager>sm=defaultServiceManager();
  24. binder=sm->getService(String16("byn.example"));
  25. LOGE("Example::getExampleService%p/n",sm.get());
  26. if(binder==0){
  27. LOGW("ExampleServicenotpublished,waiting...");
  28. return;
  29. }
  30. }
  31. };//namespace
  32. usingnamespaceandroid;
  33. intmain(intargc,char**argv)
  34. {
  35. Example*p=newExample();
  36. p->add100(1);
  37. return0;
  38. }

  1. #File:Example
  2. LOCAL_PATH:=$(callmy-dir)
  3. include$(CLEAR_VARS)
  4. LOCAL_SRC_FILES:=/
  5. Example.cpp
  6. LOCAL_C_INCLUDES:=$(JNI_H_INCLUDE)
  7. LOCAL_SHARED_LIBRARIES:=/
  8. libutilslibbinderlibExample
  9. LOCAL_PRELINK_MODULE:=false
  10. LOCAL_MODULE:=Example
  11. 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)