Binder使用示例

BInder方面的资料虽然感觉看的比较多,但是真正用的时候才发现有很多地方模棱两棵的,所以,打算用一个实例再来巩固一下binder的使用方法

首先看下目录结构:

[cpp]  view plain copy print ?
  1. leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ ls T*  
  2. TestBinderClient:  
  3. Android.mk  ITestBinderService.cpp  
  4.   
  5. TestBinderServer:  
  6. Android.mk  ITestBinderService.h  main_testBinder.cpp  testBinder.cpp  TestBinderService.cpp  TestBinderService.h  
  7. leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$   

TestBinderClient下面是Binder的客户端,TestBinderServer是binder的服务端

我们先来看下biner服务端代码


1、ITestBinderService.h

[cpp]  view plain copy print ?
  1. #ifndef ANDROID_ITESTBINDERSERVICE_H_  
  2. #define ANDROID_ITESTBINDERSERVICE_H_  
  3.   
  4. #include <utils/RefBase.h>  
  5. #include <binder/IInterface.h>  
  6. #include <binder/Parcel.h>  
  7.   
  8.   
  9. namespace android {  
  10.   
  11. class Parcel;  
  12.   
  13. class ITestBinderService: public IInterface {  
  14. public:  
  15.     DECLARE_META_INTERFACE(TestBinderService);  
  16.   
  17.     virtual int add(int a, int b) = 0;  
  18. };  
  19.   
  20. class BnTestBinderService: public BnInterface<ITestBinderService> {  
  21. public:  
  22.     virtual status_t onTransact(uint32_t code, const Parcel& data,  
  23.             Parcel* reply, uint32_t flags = 0);  
  24. };  
  25.   
  26. }  
  27.   
  28. #endif /* ANDROID_ITESTBINDERSERVICE_H_ */  

这里主要是定义了两个类ITestBinderService 和 BnTestBinderService,ITestBinderService 是TestBinderService 的基类,

这里主要是DECLARE_META_INTERFACE 这个宏,定义在frameworks\base\include\binder\IInterface.h文件中

[cpp]  view plain copy print ?
  1. #define DECLARE_META_INTERFACE(INTERFACE)                               \  
  2.     static const android::String16 descriptor;                          \  
  3.     static android::sp<I##INTERFACE> asInterface(                       \  
  4.             const android::sp<android::IBinder>& obj);                  \  
  5.     virtual const android::String16& getInterfaceDescriptor() const;    \  
  6.     I##INTERFACE();                                                     \  
  7.     virtual ~I##INTERFACE();    

把TestBinderService代入进去

[cpp]  view plain copy print ?
  1. #define DECLARE_META_INTERFACE(TestBinderService)                               \  
  2.     static const android::String16 descriptor;                          \  
  3.     static android::sp<I##TestBinderService> asInterface(                       \  
  4.             const android::sp<android::IBinder>& obj);                  \  
  5.     virtual const android::String16& getInterfaceDescriptor() const;    \  
  6.     I##TestBinderService();                                                     \  
  7.     virtual ~I##TestBinderService();   
其中封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy
2、TestBinderService.h

[cpp]  view plain copy print ?
  1. #ifndef ANDROID_TESTBINDERSERVICE_H_  
  2. #define ANDROID_TESTBINDERSERVICE_H_  
  3.   
  4. #include <utils/KeyedVector.h>  
  5. #include "ITestBinderService.h"  
  6.   
  7. namespace android {  
  8.   
  9. class TestBinderService: public BnTestBinderService {  
  10. public:  
  11.     static void instantiate();  
  12.     int add(int a,int b);  
  13. private:  
  14.     TestBinderService();  
  15.     virtual ~TestBinderService();  
  16. };  
  17.   
  18. }  
  19.   
  20. #endif /* ANDROID_TESTBINDERSERVICE_H_ */  

这个文件比较简单,主要就是定义了一个类TestBinderService,继承于前面 的BnTestBinderService,并定义了一个方法add函数和instantiate

3、TestBinderService.cpp

[cpp]  view plain copy print ?
  1. #define LOG_TAG "TestBinderService"  
  2.   
  3. #include <utils/Log.h>  
  4. #include <binder/IServiceManager.h>  
  5. #include <binder/IPCThreadState.h>  
  6.   
  7. #include "TestBinderService.h"  
  8. static int debug_flag = 1;  
  9. namespace android {  
  10.   
  11. void TestBinderService::instantiate() {  
  12.     LOGI("Enter TestBinderService::instantiate");  
  13.     status_t st = defaultServiceManager()->addService(  
  14.             String16("my.test.binder"), new TestBinderService());  
  15.     LOGD("ServiceManager addService ret=%d", st);  
  16.     LOGD("instantiate> end");  
  17. }  
  18.   
  19. TestBinderService::TestBinderService() {  
  20.     LOGD(" TestBinderServicet");  
  21. }  
  22.   
  23. TestBinderService::~TestBinderService() {  
  24.     LOGD("TestBinderService destroyed,never destroy normally");  
  25. }  
  26.   
  27. int TestBinderService::add(int a,int b) {  
  28.   
  29.     LOGI("TestBinderService::add a = %d, b = %d.", a , b);    
  30.     return a+b;  
  31. }  
  32.   
  33. }  

在instantiate函数中,将TestBinderService注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法

该service提供了一个add 方法,返回两个数的和


再来看下clinet端 的代码

1、ITestBinderService.cpp

[cpp]  view plain copy print ?
  1. #define LOG_TAG "ITeeveePlayerService"  
  2.   
  3. #include <utils/Log.h>  
  4.   
  5. #include "../TestBinderServer/ITestBinderService.h"  
  6.   
  7. namespace android {  
  8.   
  9. enum {  
  10.     TEST_ADD = IBinder::FIRST_CALL_TRANSACTION,  
  11. };  
  12.   
  13. class BpTestBinderService: public BpInterface<ITestBinderService> {  
  14. public:  
  15.     BpTestBinderService(const sp<IBinder>& impl) :  
  16.         BpInterface<ITestBinderService> (impl) {  
  17.     }  
  18.   
  19.     int add(int a, int b) {  
  20.           
  21.         Parcel data, reply;  
  22.         LOGI("Enter BpTestBinderService add,a = %d , b = %d", a, b);  
  23.         data.writeInterfaceToken(ITestBinderService::getInterfaceDescriptor());  
  24.         data.writeInt32(a);  
  25.         data.writeInt32(b);  
  26.         remote()->transact(TEST_ADD, data, &reply);  
  27.         int sum = reply.readInt32();  
  28.         LOGI("BpTestBinderService sum = %d", sum);  
  29.         return sum;  
  30.     }  
  31. };  
  32.   
  33. IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService");  
  34.   
  35. // ----------------------------------------------------------------------  
  36.   
  37. status_t BnTestBinderService::onTransact(uint32_t code, const Parcel& data,  
  38.         Parcel* reply, uint32_t flags) {  
  39.     switch (code) {  
  40.     case TEST_ADD: {  
  41.           
  42.         CHECK_INTERFACE(ITestBinderService, data, reply);  
  43.         int a = data.readInt32();  
  44.         int b = data.readInt32();  
  45.         LOGI("Enter BnTestBinderService add,a = %d , b = %d", a, b);  
  46.         int sum = 0;  
  47.         sum  = add(a, b);  
  48.         LOGI("BnTestBinderService sum = %d", sum);  
  49.          reply->writeInt32(sum);  
  50.         return sum;  
  51.     }  
  52.     default:  
  53.         return BBinder::onTransact(code, data, reply, flags);  
  54.     }  
  55. }  
  56.   
  57. }  
定义了一个类BpTestBinderService,提供add方法,该方法通过调用远端的binder service提供的服务返回两个数的和

重载了BnTestBinderService的onTransact方法,使其在TEST_ADD时调用add方法

这个文件里面也使用了一个宏IMPLEMENT_META_INTERFACE,也是定义在frameworks\base\include\binder\IInterface.h文件中

[cpp]  view plain copy print ?
  1. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \  
  2.     const android::String16 I##INTERFACE::descriptor(NAME);             \  
  3.     const android::String16&                                            \  
  4.             I##INTERFACE::getInterfaceDescriptor() const {              \  
  5.         return I##INTERFACE::descriptor;                                \  
  6.     }                                                                   \  
  7.     android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \  
  8.             const android::sp<android::IBinder>& obj)                   \  
  9.     {                                                                   \  
  10.         android::sp<I##INTERFACE> intr;                                 \  
  11.         if (obj != NULL) {                                              \  
  12.             intr = static_cast<I##INTERFACE*>(                          \  
  13.                 obj->queryLocalInterface(                               \  
  14.                         I##INTERFACE::descriptor).get());               \  
  15.             if (intr == NULL) {                                         \  
  16.                 intr = new Bp##INTERFACE(obj);                          \  
  17.             }                                                           \  
  18.         }                                                               \  
  19.         return intr;                                                    \  
  20.     }                                                                   \  
  21.     I##INTERFACE::I##INTERFACE() { }                                    \  
  22.     I##INTERFACE::~I##INTERFACE() { }   
代入展开后:
[cpp]  view plain copy print ?
  1. #define IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService")                       \  
  2.     const android::String16 ITestBinderService::descriptor("android.test.ITestBinderService");             \  
  3.     const android::String16&                                            \  
  4.             ITestBinderService::getInterfaceDescriptor() const {              \  
  5.         return ITestBinderService::descriptor;                                \  
  6.     }                                                                   \  
  7.     android::sp<ITestBinderService> ITestBinderService::asInterface(                \  
  8.             const android::sp<android::IBinder>& obj)                   \  
  9.     {                                                                   \  
  10.         android::sp<ITestBinderService> intr;                                 \  
  11.         if (obj != NULL) {                                              \  
  12.             intr = static_cast<ITestBinderService*>(                          \  
  13.                 obj->queryLocalInterface(                               \  
  14.                         ITestBinderService::descriptor).get());               \  
  15.             if (intr == NULL) {                                         \  
  16.                 intr = new BpTestBinderService(obj);                          \  
  17.             }                                                           \  
  18.         }                                                               \  
  19.         return intr;                                                    \  
  20.     }                                                                   \  
  21.     ITestBinderService::ITestBinderService() { }                                    \  
  22.     ITestBinderService::~ITestBinderService() { }     

这里重点看 一下asInterface函数,IBinder::queryLocalInterface函数位于framework/base/libs/binder/Binder.cpp文件中

[cpp]  view plain copy print ?
  1. sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)  
  2. {  
  3.     return NULL;  
  4. }  
由此可见,最终会调用下面语句:
 intr = new BpTestBinderService(obj)


这样,server和client端的binder代码主写好了,接着就需要把binder service加入到binder中

这里有两种方法:

1、在system_init.cpp中添加

TestBinderService::instantiate();

如果是在这里加的话可以去掉TestBinderService中实现的instantiate方法,同时将TestBinderService继承自BinderService,因为在BinderService实现了这一方法,同时将其添加到binder service

2、以单独的程序启动

main_testBinder.cpp

[cpp]  view plain copy print ?
  1. #include <binder/IPCThreadState.h>  
  2. #include <binder/ProcessState.h>  
  3. #include <binder/IServiceManager.h>  
  4. #include <utils/Log.h>  
  5.   
  6.   
  7. #include "TestBinderService.h"  
  8.   
  9. using namespace android;  
  10.   
  11. int main(int argc, char** argv)  
  12.  {  
  13.       
  14.     sp<ProcessState> proc(ProcessState::self());  
  15.     sp<IServiceManager> sm = defaultServiceManager();  
  16.     LOGI("TestBinderService before");  
  17.     TestBinderService::instantiate();  
  18.     LOGI("TestBinderService End");  
  19.     ProcessState::self()->startThreadPool();  
  20.     IPCThreadState::self()->joinThreadPool();  
  21.     return 0;  
  22.   
  23. }  

这里调用的是TestBinderService自己的instantiate来添加的


再来看下测试case,testBinder.cpp

[cpp]  view plain copy print ?
  1. #define LOG_TAG "TestBinserService"  
  2.   
  3. #include <utils/Log.h>  
  4. #include <nativehelper/jni.h>  
  5. #include <nativehelper/JNIHelp.h>  
  6. #include <android_runtime/AndroidRuntime.h>  
  7. #include <binder/IServiceManager.h>  
  8. #include "../TestBinderServer/ITestBinderService.h"  
  9.   
  10.   
  11. #include "TestBinderService.h"  
  12.   
  13. using namespace android;  
  14.   
  15. int main(int argc, char** argv)  
  16.  {  
  17.     int sum = 0;  
  18.     sp<ITestBinderService> mTestBinserService;  
  19.     if (mTestBinserService.get() == 0) {  
  20.         sp<IServiceManager> sm = defaultServiceManager();  
  21.         sp<IBinder> binder;  
  22.         do {  
  23.             binder = sm->getService(String16("my.test.binder"));  
  24.             if (binder != 0)  
  25.                 break;  
  26.                 LOGI("getService fail");  
  27.             usleep(500000); // 0.5 s  
  28.         } while (true);  
  29.         mTestBinserService = interface_cast<ITestBinderService> (binder);  
  30.         LOGE_IF(mTestBinserService == 0, "no ITestBinserService!?");  
  31.     }  
  32.     sum = mTestBinserService->add(3, 4);  
  33.     LOGI("sum = %d", sum);  
  34.     return 0;  
  35.   
  36. }  

这里先根据名字获取Service,再使用其提供的相应 服务

看下串口打印,

启动service:

[cpp]  view plain copy print ?
  1. C:\adb>adb shell  
  2. # cd /system/bin  
  3. cd /system/bin  
  4. # chmod 777 main_*  
  5. chmod 777 main_*  
  6. # ./main_testBinder  
  7. ./main_testBinder  

client:

[cpp]  view plain copy print ?
  1. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  2. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  3. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  4. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  5. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  6. I/PlayServiceManager-JNI( 1369): getService fail  
  7. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  8. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  9. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  10. I/ServiceManager( 1369): Waiting for service my.test.binder...  
  11. I/        ( 1373): TestBinderService before  
  12. I/TestBinderService( 1373): Enter TestBinderService::instantiate  
  13. D/TestBinderService( 1373):  TestBinderServicet  
  14. D/TestBinderService( 1373): ServiceManager addService ret=0  
  15. D/TestBinderService( 1373): instantiate> end  
  16. I/        ( 1373): TestBinderService End  
  17. I/ITeeveePlayerService( 1369): Enter BpTestBinderService add,a = 3 , b = 4  
  18. I/ITeeveePlayerService( 1373): Enter BnTestBinderService add,a = 3 , b = 4  
  19. I/TestBinderService( 1373): TestBinderService::add a = 3, b = 4.  
  20. I/ITeeveePlayerService( 1373): BnTestBinderService sum = 7  
  21. I/ITeeveePlayerService( 1369): BpTestBinderService sum = 7  
  22. I/PlayServiceManager-JNI( 1369): sum = 7  
前面 的Waiting for service my.test.binder...是在还没有启动service的时候打印出来的

这样,需要使用TestBinserService 提供的服务时,只需要先获取其service,再使用其提供的方法

相关代码:

http://download.csdn.net/detail/new_abc/4673623


你可能感兴趣的:(Binder使用示例)