C++使用binder实例

Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。

这是一个用C++写的binder,一个服务器一恶搞客户端,代码如下:

server.cpp

  1 #include <binder/IServiceManager.h>
  2 #include <binder/IBinder.h>
  3 #include <binder/Parcel.h>
  4 #include <binder/ProcessState.h>
  5 #include <binder/IPCThreadState.h>
  6 #include <android/log.h>
  7 using namespace android;
  8 #ifdef LOG_TAG
  9 #undef LOG_TAG
 10 #endif
 11 #define LOG_TAG "testService"
 12
 13 #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__)
 14 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ProjectName", __VA_ARGS__)
 15 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO  , "ProjectName", __VA_ARGS__)
 16 #define LOGW(...) __android_log_print(ANDROID_LOG_WARN  , "ProjectName", __VA_ARGS__)
 17 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "ProjectName", __VA_ARGS__)
 18
 19 class MyService : public BBinder
 20 {
 21 public:
 22     MyService()
 23     {
 24         mydescriptor = String16("media.hello");
 25         n=0;
 26     }
 27     virtual ~MyService() {}
 28     //This function is used when call Parcel::checkInterface(IBinder*)
 29     virtual const String16& getInterfaceDescriptor() const
 30     {
 31         LOGE("this is enter ==========getInterfaceDescriptor");
 32         return mydescriptor;
 33     }
 34 protected:
 35     void show()
 36     {
 37         LOGE("this is for test show!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 38         LOGE("this is for test show!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 39         LOGE("this is for test show!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 40         LOGE("this is for test show!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 41         LOGE("this is for test show!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 42     }
 43     virtual status_t onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0)
 44     {
 45         LOGD("enter MyService onTransact and the code is %d",code);
 46         /*
 47         if (data.checkInterface(this))
 48         LOGD("checkInterface OK");
 49         else
 50         {
 51         LOGW("checkInterface failed");
 52         return BBinder::onTransact(code, data, reply, flags);
 53         }
 54         */
 55         switch (code)
 56         {
 57             case 1:
 58                 LOGD("MyService interface 1");
 59                 break;
 60             case 2:
 61                 LOGD("MyService interface 2");
 62                 cb = data.readStrongBinder();
 63                 break;
 64             case 3:
 65             {
 66                 LOGD("MyService interface 3, exit");
 67                 //No unregister service routine?
 68                 //It should return to client first and then call exit in another place.
 69                 exit(0);
 70                 break;
 71             }
 72             case 4:
 73             {//call cb
 74                 LOGD("MyService interface 4 before if================");
 75                 cb = data.readStrongBinder();
 76                 if (cb != NULL)
 77                 {
 78                     LOGD("MyService interface 4");
 79                     Parcel in, out;
 80                     in.writeInterfaceToken(String16("android.os.ISetupCallback"));
 81                     in.writeInt32(n++);
 82                     //in.writeString16(String16("This is a string."));
 83                     in.writeCString("This is a string !");
 84                     cb->transact(2, in, &out, 0);
 85                     show();
 86                 }
 87                 break;
 88             }
 89             default:
 90                 return BBinder::onTransact(code, data, reply, flags);
 91         }
 92         return 0;
 93     }
 94 private:
 95     String16 mydescriptor;
 96     sp<IBinder> cb;
 97     int n;
 98 };
 99 int main()
100 {
101     sp<IServiceManager> sm = defaultServiceManager(); //获取ServiceManager服务代理
102     status_t ret;
103     //register MyService to ServiceManager
104     MyService* srv = new MyService();
105     ret = sm->addService(String16("media.hello"), srv); // 注册服务
106     LOGD("addservice media.hello return %d", ret);
107     //call binder thread pool to start
108     ProcessState::self()->startThreadPool();
109     IPCThreadState::self()->joinThreadPool(true); //参数默认也是true,进入服务的循环监听状态
110     return 0;
111 }

clinet.cpp

 1 #include <binder/IServiceManager.h>
 2 #include <binder/IBinder.h>
 3 #include <binder/Parcel.h>
 4 #include <binder/ProcessState.h>
 5 #include <binder/IPCThreadState.h>
 6 #include <private/binder/binder_module.h>
 7 #include <android/log.h>
 8
 9 using namespace android;
10 #ifdef LOG_TAG
11 #undef LOG_TAG
12 #endif
13 #define LOG_TAG "testCallback"
14
15 #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__)
16 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ProjectName", __VA_ARGS__)
17 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO  , "ProjectName", __VA_ARGS__)
18 #define LOGW(...) __android_log_print(ANDROID_LOG_WARN  , "ProjectName", __VA_ARGS__)
19 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "ProjectName", __VA_ARGS__)
20
21 class MySetupCallback : public BBinder
22 {
23 public:
24     MySetupCallback()
25     {
26         mydescriptor = String16("android.os.ISetupCallback");
27     }
28     virtual ~MySetupCallback() {}
29     virtual const String16& getInterfaceDescriptor() const
30     {
31         return mydescriptor;
32     }
33 protected:
34     virtual status_t onTransact( uint32_t code,    const Parcel& data,    Parcel* reply,    uint32_t flags = 0)
35     {
36         LOGD("enter MySetupCallback onTransact, code=%u", code);
37         if (data.checkInterface(this)) //检查 mydescriptor 类描述字符串
38             LOGD("checkInterface OK");
39         else
40         {
41             LOGW("checkInterface failed");
42             return -1;
43         }
44         switch (code) //code为服务器发送的code,根据code实现不同的函数
45         {
46             case 1:
47                 LOGD("From Server code = %u", code);
48                 LOGD("From Server code = %u", code);
49                 break;
50             case 2:
51             {
52                 LOGD("From Server code = %u", code);
53
54                 //LOGD("String from server: %s", reply->readCString());
55
56                 break;
57             }
58             default:
59             break;
60         }
61         return 0;
62     }
63 private:
64     String16 mydescriptor;
65 };
66
67 int main()
68 {
69     sp<IServiceManager> sm = defaultServiceManager();   //获取ServiceManager服务代理
70     sp<IBinder> b = sm->getService(String16("media.hello")); //查询服务
71     if (b == NULL)
72     {
73         LOGW("Can‘t find binder service \"media.hello\"");
74         return -1;
75     }
76     Parcel in1,out1;
77     MySetupCallback *cb = new MySetupCallback();
78     in1.writeStrongBinder(sp<IBinder>(cb));
79     int ret = b->transact(4, in1, &out1, 0); //TRANSACTION_registerSetup = 4
80     LOGD("transact(4) return %d", ret);
81     ProcessState::self()->startThreadPool();
82     IPCThreadState::self()->joinThreadPool(); //参数默认也是true,进入服务的循环监听状态
83     return 0;
84 }

Android.mk

# Copyright 2006 The Android Open Source Project
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES :=     libcutils     libbinder     libutils     libhardware
LOCAL_SRC_FILES:=  client.cpp
LOCAL_MODULE_TAGS = eng tests
LOCAL_MODULE:= testClient
include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES :=     libcutils     libbinder     libutils     libhardware
LOCAL_SRC_FILES:=server.cpp
LOCAL_MODULE:= testServer
LOCAL_MODULE_TAGS = eng tests
include $(BUILD_EXECUTABLE)

以上代码参考别人写的做了点修改,有错误的地方欢迎指出来,谢谢。

时间: 2025-02-01 16:56:23

C++使用binder实例的相关文章

自顶向下分析Binder【1】—— Binder实例篇

欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 一个Binder实例 我们Binder的学习将从以下的一个实例開始.依据Android文档中的描写叙述,创建一个Binder服务主要包含例如以下3步: 以下详细看一下在eclipse中是怎样开发一个Binder应用的. 第一步:在project文件夹下定义aidl文件. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.zxh.ipc; import com.zxh.i

安卓binder机制浅析

Binder机制是android系统中跨进程通信的重要手段.其中,Service与Activity的交互通信使用到了这一机制.为此,我写了service的小案例,以此来方便更好地理解binder通信机制. Service代码: public class MyService extends Service { public boolean flag=true; int count; //实例化一个binder ServiceBinder serviceBinder=new ServiceBinde

零基础理解Binder

写在前面的 当一个Android App存在某个不需要UI的后台运行需求时,或者是因为内存占用需要采用多进程方案时,我们免不了与多进程打交道.必不可少的,需要考虑Binder在其中如何实现. 最常见的Binder实现当然是AIDL,然而Binder的实现绝不仅仅只有AIDL一种方式,如果止步于写.aidl,那么对于Binder,对于Android整体的跨进程传输过程的理解都只能流于形式. 但是想理解Binder不是一件容易的事情,Binder的概念涉及太多知识点,遍观各大论坛上关于Binder的

Android Binder机制完全解析

概述 之前我写过一篇文章Android Service全面解析,简单实现了如何通过AIDL实现Service的跨进程通信(IPC),其实是通过Binder机制来实现的,本文我们就重点来看看Binder机制的原理. Binder可以提供系统中任何程序都可以访问的全局服务.这个功能当然是任何系统都应该提供的,下面我们简单看一下Android的Binder的框架: Android Binder框架分为服务器接口.Binder驱动.以及客户端接口:简单想一下,需要提供一个全局服务,那么全局服务那端即是服

浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划简要介绍了Android系统进程间通信机制Binder的总体架构,它由Client.Server.Service Manager和驱动程序Binder四个组件构成.本文着重介绍组件Service Manager,它是整个Binder机制的守护进程,用来管理

(转载)Android中的Service:Binder,Messenger,AIDL(2)

前言 前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等.在这一篇博文里有一些需要前一篇铺垫的东西,建议没有看过前一篇博文的同学先去看一下前一篇: Android中的Service:默默的奉献者 (1) . 但是在前一篇博文中也有一些遗漏的东西--主要是关于bindService()这一块的具体细节.由于这一块涉及的东西还是比较多,所以在这里单独提出来了.闲话不多说,进入正文. 1.bindServ

android Binder机制

Binder 架构设计 Binder 被设计出来是解决 Android IPC(进程间通信) 问题的.Binder 将两个进程间交互的理解为 Client 向 Server 进行通信. 如下:binder总体架构图 如上图所示,Binder 架构分为 Client.Server.Service Manager 和 Binder Driver. Client: 服务调用者,一般就是我们应用开发者,通过调用诸如List<PackageInfo> packs = getActivity().getP

Android aidl Binder框架浅析

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38461079 ,本文出自[张鸿洋的博客] 1.概述 Binder能干什么?Binder可以提供系统中任何程序都可以访问的全局服务.这个功能当然是任何系统都应该提供的,下面我们简单看一下Android的Binder的框架 Android Binder框架分为服务器接口.Binder驱动.以及客户端接口:简单想一下,需要提供一个全局服务,那么全局服务那端即是服务器接口,任何程序即客

Android AIDL实例解析

AIDL这项技术在我们的开发中一般来说并不是很常用,虽然自己也使用新浪微博的SSO登录,其原理就是使用AIDL,但是自己一直没有动手完整的写过AIDL的例子,说来丢人呐,所以就有了这篇简单的文章.        AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数),