C++实例讲解Binder通信

  binder是android里面的通信机制,这就不说它如何如何好了,Goog已经说过了,这里不多说。binder是一个面向对象的编程方法,大量使用虚函数类。最近研究binder看到一网友写的,就借鉴一下。这个例子很好的解释里binder通信关系。原文:http://blog.csdn.net/new_abc/article/details/8097775 例子不错不过就是没运行起来,不过这都不是问题,关键是很容易理解。

  我将他的源码整理类图看看,不过这个是简单的继承关系。

  

  基本上使用binder就这个关系,从中间一分为二,左边客户端使用,右边服务端。不管是客户端还是服务端都继承子IXXXService这个类,这个类可以裂解为客户端和服务端的“爷爷”,而“爷爷”继承IInterface,所有自定义的binder都必须继承这个类,这个是android强指针实现计数的方法。先看看源码后再理解这个图。

首先看下目录结构:

  TestBinderClient目录:  Android.mk  ITestBinderService.cpp

  TestBinderServer目录: Android.mk  ITestBinderService.h  main_testBinder.cpp  testBinder.cpp  TestBinderService.cpp  TestBinderService.h  

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

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

1、ITestBinderService.h

 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.h

      这里主要是定义了两个类ITestBinderService 和 BnTestBinderService,ITestBinderService 是TestBinderService 的基类,这里主要是DECLARE_META_INTERFACE 这个宏,定义在frameworksaseincludeinderIInterface.h文件中。

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();   
DECLARE_META_INTERFACE 宏

把TestBinderService代入进去

1 #define DECLARE_META_INTERFACE(TestBinderService)                                 
2     static const android::String16 descriptor;                            
3     static android::sp<ITestBinderService> asInterface(                         
4             const android::sp<android::IBinder>& obj);                    
5     virtual const android::String16& getInterfaceDescriptor() const;      
6     ITestBinderService();                                                       
7     virtual ~I##TestBinderService();  
带入宏后

其中封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy(代理)

2、TestBinderService.h

 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.h

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

3、TestBinderService.cpp

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

在instantiate函数中,将TestBinderService注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法,该service提供了一个add 方法,返回两个数的和。

再来看下clinet端 的代码

1、ITestBinderService.cpp

 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     }  
ITestBinderService.cpp

定义了一个类BpTestBinderService,提供add方法,该方法通过调用远端的binder service提供的服务返回两个数的和重载了BnTestBinderService的onTransact方法,使其在TEST_ADD时调用add方法

这个文件里面也使用了一个宏IMPLEMENT_META_INTERFACE,也是定义在frameworksaseincludeinderIInterface.h文件中

 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() { }   
IMPLEMENT_META_INTERFACE宏

代入展开后:

 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() { } 
带入到宏后

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

这里有两种方法:

1、在system_init.cpp中添加

TestBinderService::instantiate();

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

2、以单独的程序启动

main_testBinder.cpp

 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     }  
将server添加到servermanage里面

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

再来看下测试testBinder.cpp

 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     }  
testBinder.cpp

以上就是测试代码。

原文地址:https://www.cnblogs.com/winfu/p/5853586.html