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 这个宏,定义在frameworks\base\include\binder\IInterface.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,也是定义在frameworks\base\include\binder\IInterface.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回收对象以提高性能

总览 在上一篇文章中&#xff0c;我说过对象反序列化更快的原因是由于使用了回收对象。 由于两个原因&#xff0c;这可能令人惊讶&#xff1a;1&#xff09;相信如今创建对象是如此之快&#xff0c;无关紧要或与回收自己一样快&#xff0c;2&#xff09;默认情况下&#xff0c;…

oj系统格式错误_论文查重会不会检查格式?【paperpp吧】

高等学校一般都会要求大学生在毕业时需要写作毕业论文&#xff0c;并且会提前发出关于毕业论文的通知&#xff0c;在通知上一般会说明论文写作的相关要求&#xff0c;其中就会规定论文的相关格式。当然&#xff0c;学校也会在通知中说明论文查重的相关事宜&#xff0c;那么论文…

usb大容量存储设备驱动_usb无法识别怎么办 如何解决usb识别故障【详细步骤】...

usb无法识别怎么办? 随着计算机硬件飞速发展&#xff0c;外围设备日益增多&#xff0c;键盘、鼠标等早已为人所共知&#xff0c;数码相机、MP3随身听接踵而至&#xff0c;这么多的设备&#xff0c;如何接入个人计算机?USB就是基于这个目的产生的。USB是一个使计算机周边设备连…

Java EE过去,现在和云7

最近的JavaOne 2011的一个突出主题是下一个主要的Java EE 7版本。 正如主题发言中所述&#xff0c;有关工作正在进行中。 它将包含我们已经从先行者那里知道的28个规范以及一些新规范。 没人可以告诉您确切的号码&#xff0c;因为EE 7仅在“及时”完成时才会接受新的规范。 这意…

程序员都用什么来记录知识_1年前的小五都用 Python 来做什么?

↑ 点击上方 “凹凸数据” 关注 星标 ~ 每天更新&#xff0c;干货不断 (多图预警)注&#xff1a;这是小五一年前在知乎的回答&#xff0c;当时还只有凹凸数读一个公众号&#xff0c;所以很多图片都会带有数读或者知乎的水印。作为一个菜鸟数据分析师&#xff0c;只会sqlpytho…

SQL-行转列(PIVOT)实例1

--未旋转之前的查询结果 select s.Name ShiftName,h.BusinessEntityID,d.Name as DpartmentName from HumanResources.EmployeeDepartmentHistory h inner join HumanResources.Department d on h.DepartmentIDd.DepartmentIDinner join HumanResources.Shift s on s.ShiftIDh…

webservice接口_webservice服务器端发票识别接口

关键词&#xff1a;发票识别 私有云发票识别 发票识别API接口 webservice发票识别平台发票&#xff0c;一个再也熟悉不过的财务往来凭证&#xff0c;录入发票&#xff0c;一项让多少财会人员头疼的工作。过去录入一张发票需要一个财会人员5分钟的时间&#xff0c;那么这个人在工…

一个简单的socket通信小demo

写了一个socket的程序&#xff0c;可以和本地的服务器进行通信&#xff0c;要先和服务器建立链接&#xff0c;然后发送登录信息&#xff0c;验证成功&#xff0c;就可以和服务器通信了 1 页面截图 2 点击链接服务器&#xff0c;可以链接服务器&#xff0c;服务器的ip地址为&…

汉仪尚巍手书可以商用吗_【商用车维修】夏天修空调可以撑起全年修车收入的一半,你会了吗?...

更多精彩&#xff0c;请点击上方蓝字关注我们&#xff01;车载空调是炎热的季节必不可少的利器&#xff0c;但用得多&#xff0c;毛病也多了起来&#xff0c;今天和大家分享一些空调系统的相关知识&#xff0c;助力修车师傅们来应对空调系统的相关故障问题。如何判断制冷系统的…

Git 简单使用

1.Git是什么 简介&#xff1a;Git是 Linux 之父 Linus Trovalds&#xff0c;为管理 Linux 内核代码而建立的&#xff0c;被认为是分布式版本控制工具中的顶级水准。智能、友好、强健、高效。 作用&#xff1a;新建一个分支&#xff0c;把服务器上最新版的代码fetch下来&#x…

Vaadin附加组件和Maven

介绍 我喜欢Vaadin的 &#xff08;众多&#xff09;一件事是它对Vaadin框架的“附加组件”社区-他们称之为Vaadin目录 。 “附加组件”是框架中社区贡献的附加组件&#xff0c;可以是任何东西&#xff0c;例如从新的客户端小部件到数据表的延迟加载容器。 我肯定会为Activiti看…

八皇后时间复杂度_【算法打卡】N皇后

难度&#xff1a;困难题目&#xff1a;n 皇后问题研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。上图为 8 皇后问题的一种解法。给定一个整数 n&#xff0c;返回 n 皇后不同的解决方案的数量。提示&#xff1a;皇后&#xff0c;是国际…

Android-Binder 简析

前言 对于Android来说&#xff0c;Binder的重要性怎么说都不为过。不管是我们的四大组件Activity、Service、BroadcastReceiver、ContentProvider&#xff0c;还是经常在应用中使用到的各种ServiceManager&#xff0c;其背后都是Binder在支撑。然而Binder机制又不是三言两语能够…

tplink 703刷固件

1.软件下载: ImageBuilder链接 如果是全新刷机的话,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin 如果是系统升级的话,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/op…

编程反模式

您是否曾经进行过代码审查&#xff0c;记录了非常高的WTF / m&#xff1f; 您是否想知道所有这些错误代码的原因是什么&#xff1f; 在大多数情况下&#xff0c;导致原因1的主要原因是使用设计和编码反模式。 如果您喜欢定义&#xff0c;请参见以下内容&#xff1a;AntiPatter…

sql 插入text字段包含特殊字符_Kettle(PDI)转换中输出之插入/更新详解

概述Insert / update(插入 / 更新)此步骤首先使用一个或多个查询关键字查找表中的一行。如果找不到该行&#xff0c;则插入该行。如果可以找到它&#xff0c;并且要更新的字段相同&#xff0c;则不执行任何操作。如果它们不完全相同&#xff0c;则更新表中的行。注意&#xff1…

一张图让你看清Java集合类(Java集合类的总结)

如今关于Java集合类的文章非常多&#xff0c;可是我近期看到一个非常有意思图片&#xff0c;基本上把Java集合的整体框架都给展现出来了。非常直观。 假设发现图片看不清楚。点此处看大图 在这里&#xff0c;集合类分为了Map和Collection两个大的类别。 处于图片左上角的那一块…

【P1835】小红花

很简单的题&#xff0c;然而我没想到&#xff0c;在NOIP上怎么办嘛QAQ 话说这题不知道怎么分类啊……先扔到玄学里边把…… 原题&#xff1a; Fj在圣诞节来临之际&#xff0c;决定给他的奶牛发一些小红花。现在Fj一共有N头奶牛&#xff0c;这N头牛按照编号1..N&#xff0c;排成…

Cocos2d-x 3.2 Lua演示样例FontTest(字体測试)

Cocos2d-x 3.2 Lua演示样例FontTest&#xff08;字体測试&#xff09;本篇博客介绍Cocos2d-x 3.2中Lua測试项目中的FontTest样例&#xff0c;主要使用了字体文件来创建我们想要的字体样式&#xff1a;第一个參数为文本。第二參数为ttf字体文件&#xff0c;第三个參数为字体大小…

linux上安装memcached步骤

libevent: http://libevent.org/ 服务器端&#xff1a;https://code.google.com/archive/p/memcached/downloads 客户端&#xff1a; http://pecl.php.net/package/memcache 和 http://pecl.php.net/package/memcached 二选一 http://chenzhou123520.iteye.com/blog/1…