zoukankan      html  css  js  c++  java
  • 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

    以上就是测试代码。

  • 相关阅读:
    PHP $_SERVER['HTTP_REFERER'] 获取前一页面的 URL 地址
    LAMP与LNMP架构的区别及其具体的选择说明
    LNMP 与 LAMP 架构的区别及配置解决方案
    LAMP和LNMP,你更愿意选择谁,为什么?
    Storm流计算从入门到精通之技术篇(高并发策略、批处理事务、Trident精解、运维监控、企业场景)
    Zookeeper从入门到精通(开发详解,案例实战,Web界面监控)
    基于Greenplum Hadoop分布式平台的大数据解决方案及商业应用案例剖析
    深入浅出Hive企业级架构优化、Hive Sql优化、压缩和分布式缓存(企业Hadoop应用核心产品)
    深入浅出OpenStack云计算平台管理(nova-compute/network)
    玩转大数据:深入浅出大数据挖掘技术(Apriori算法、Tanagra工具、决策树)
  • 原文地址:https://www.cnblogs.com/winfu/p/5853586.html
Copyright © 2011-2022 走看看