Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

    • 000.Binder 专题导学 —— 如何深入掌握 Binder
    • 001.学习 Binder 的预备知识
    • 002.Binder 基本原理
    • 003.Binder 程序示例之 C 语言篇
    • 004.Binder 服务注册过程情景分析之 C 语言篇
    • 005.Binder 服务获取与使用过程情景分析之C语言篇
    • 006.Android Binder 驱动框架设计与分析
    • 007.Binder 驱动情景分析之 ServiceManager 启动过程
    • 008.Binder 驱动情景分析之服务注册过程
    • 009.Binder 驱动情景分析之服务获取与使用过程
    • 010.Binder 程序示例之 C++ 篇
      • 1. 定义通信协议
      • 2. 通信协议服务端实现
      • 3. 通信协议客户端协议实现
      • 4. 服务端程序实现
      • 5. 客户端程序实现
      • 6. 编译运行
    • 011.Binder C++ 程序分析之主要类解析
    • 012.Binder 服务注册过程情景分析之 C++ 篇
    • 013.Binder 服务获取与使用过程情景分析之C++篇
    • 014.Binder 程序示例之 aidl-cpp 篇
    • 015.添加 Android Native 系统服务
    • 016.添加 Native 系统服务回调
    • 017.Binder 程序示例之 Java 篇
    • 018.Binder Java 层初始化
    • 019.Binder Java 层服务注册过程分析
    • 020.Binder Java 层服务获取与使用过程分析
    • 021.添加 Java 系统服务
    • 022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务
    • 023.添加 Java 系统服务回调
    • 024.AIDL 数据类型详解之 Java 篇
    • 025.AIDL 数据类型详解之 C++ 篇
    • 026.Java 调用 Native 服务
    • 027.Native 调用 Java Binder 服务
    • 028.AIDL 关键字 in out inout oneway 解析
    • 029.Binder 驱动 Debug 入门指南
    • 030.Binder 匿名服务源码分析
    • 031.Binder 中的 Parcel 数据结构分析(C++)
    • 032.Binder 中的 Parcel 数据结构分析(Java)
    • 033.Binder 多线程情景分析
    • 034.Binder 线程池溢出问题
    • 035.Binder 代理对象泄露问题分析
    • 036.Binder 死亡通知情景分析
    • 037.Binder 异常处理机制
    • 038.Binder 系统源码演进
    • 039.Binder 面试题汇总
    • 补充——LocalService
  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

  • Framework
  • 学穿Binder篇
阿豪
2023-07-26
目录

010.Binder 程序示例之 C++ 篇

本文基于 Android10 源码环境

Android 源码中提供了一系列的 C++ 类(libbinder 库)来简化 Binder 驱动的使用。使得开发者能快速在 Android 系统源码中添加 Binder 服务和使用 Binder 服务。接下来我们使用 Android 源码中提供的辅助类和 C++ 语言来编写一个 Binder C++ 示例程序。

可以在这里 (opens new window)下载到示例程序。

使用 C++ 实现一个 Binder 服务分为以下几步:

  • 定义协议
  • 实现服务端协议
  • 实现客户端协议
  • 服务端程序实现
  • 客户端程序实现

# 1. 定义通信协议

通信协议由三部分组成:

  • 通信协议接口
  • 通信协议服务端实现
  • 通信协议客户端实现

接下来我们来实现通信协议接口 IHelloService, 接口继承自 IInterface,描述了名为 Hello 的 Binder 服务对外提供的功能。

//IHelloService.h  类名的起始字母需要是大写的 I
class IHelloService: public IInterface {

public:
    //DECLARE_META_INTERFACE 是一个宏,声明了一些变量和函数
    DECLARE_META_INTERFACE(HelloService);
    //Binder 服务对外提供的功能
    virtual void sayHello() = 0;
    virtual int sayHelloTo(const char *name) = 0;

};
1
2
3
4
5
6
7
8
9
10
11

# 2. 通信协议服务端实现

通信协议服务端实现是一个继承自 BnInterface<IHelloService> 的类:

//声明
//IHelloService.h
class BnHelloService: public BnInterface<IHelloService> {

public:
    //服务端收到数据后的回调
    status_t onTransact(uint32_t code, const Parcefl& data, Parcel* reply, uint32_t lags = 0);
    void sayHello();
    int sayHelloTo(const char *name);
};


//实现
//BnHelloService.cpp
#define LOG_TAG "HelloService"
#include <log/log.h>
#include "IHelloService.h"


//服务端收到数据的回调
status_t BnHelloService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    //code 表示客户端需要调用哪个函数
    switch(code) {
        //调用 sayhello
        case HELLO_SVR_CMD_SAYHELLO:  {
            //调用 sayhello 函数
            sayHello();
            //写入回复给客户端的数据
            reply->writeInt32(0);
            return NO_ERROR;
        } break;
        //调用 sayhelloto
        case HELLO_SVR_CMD_SAYHELLO_TO: {
            //取出客户端发送的参数
            int32_t policy =  data.readInt32();
			String16 name16_tmp = data.readString16(); 

			String16 name16 = data.readString16();
			String8 name8(name16);
            //调用 sayHelloTo 函数
			int cnt = sayHelloTo(name8.string());
            //写入回复给客户端的数据
			reply->writeInt32(0); 
			reply->writeInt32(cnt);

            return NO_ERROR;
        } break;
  
        default:
            return BBinder::onTransact(code, data, reply, flags);
  
    }
}

//服务端函数的具体实现
void BnHelloService::sayHello() {
    static int count = 0;
    ALOGI("say hello :%d\n ", ++count);
}

int BnHelloService::sayHelloTo(const char *name) {
    static int cnt = 0;
	ALOGI("say hello to %s : %d\n", name, ++cnt);
	return cnt;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

为叙述方便我们称 BnHelloService 以及同类型的类为 Binder 服务类

# 3. 通信协议客户端协议实现

客户端协议实现是一个继承自 BpInterface<IHelloService> 的类

//客户端
//IHelloService.h
class BpHelloService: public BpInterface<IHelloService> {
public:
    BpHelloService(const sp<IBinder>& impl);
    void sayHello();
    int sayHelloTo(const char *name);
};


//BpHelloService.cpp
#include "IHelloService.h"

//调用父类构造函数
BpHelloService::BpHelloService(const sp<IBinder>& impl):BpInterface<IHelloService>(impl) {

}

void BpHelloService::sayHello() {
    Parcel data, reply;
    data.writeInt32(0);
    data.writeString16(String16("IHelloService"));
    //发起远程调用
    remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);
}

int BpHelloService::sayHelloTo(const char *name) {
    Parcel data, reply;
    int exception;

    data.writeInt32(0);
    data.writeString16(String16("IHelloService"));
    data.writeString16(String16(name));
    //发起远程调用
    remote()->transact(HELLO_SVR_CMD_SAYHELLO_TO, data, &reply);
    exception = reply.readInt32();
	if (exception)
		return -1;
	else
		return reply.readInt32();
}

    IMPLEMENT_META_INTERFACE(HelloService, "IHelloService");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

为叙述方便我们称 BpHelloService 以及同类型的类为 Binder 代理类

# 4. 服务端程序实现

int main(int argc, char const *argv[])
{
    //使用 ProcessState 类完成 binder 驱动的初始化
    sp<ProcessState> proc(ProcessState::self());
    //注册服务
    sp<IServiceManager> sm = defaultServiceManager();
    sm->addService(String16("hello"), new BnHelloService());

    //开启 binder 线程池
	ProcessState::self()->startThreadPool();
    //加入线程池
	IPCThreadState::self()->joinThreadPool();
  
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 5. 客户端程序实现

int main(int argc, char const *argv[])
{
    //使用 ProcessState 类完成 binder 驱动的初始化
    sp<ProcessState> proc(ProcessState::self());
    //获取 hello 服务
    sp<IServiceManager> sm = defaultServiceManager();
    //返回的是 BpBinder 指针
    sp<IBinder> binder = sm->getService(String16("hello"));
    sp<IHelloService> service = interface_cast<IHelloService>(binder);

    if (binder == 0)
	{
		ALOGI("can't get hello service\n");
		return -1;
	}

    //发起远程调用
    service->sayHello();
    int cnt = service->sayHelloTo("nihao");
	ALOGI("client call sayhello_to, cnt = %d", cnt);

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 6. 编译运行

项目根目录下添加 Android.bp:

cc_binary {
    name: "MyCppBinderServer",
    srcs: ["BinderServer.cpp", "BnHelloService.cpp","BpHelloService.cpp"],
    shared_libs: [
        "liblog",
        "libcutils",
        "libutils",
        "libbinder",
    ],
}


cc_binary {
    name: "MyCppBinderClient",
    srcs: ["BinderClient.cpp", "BpHelloService.cpp"],
    shared_libs: [
        "liblog",
        "libcutils",
        "libutils",
        "libbinder",
    ],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

将项目放到 aosp 任意目录下,然后执行以下命令:

source build/envsetup.sh
lunch aosp_x86_64-eng
#启动模拟器
emulator
1
2
3
4

进入到项目目录 device/jelly/rice14/BinderCppDemo,然后执行单编命令:

mm
1

编译完成后,将程序上传到模拟器并执行。

传输可执行文件到模拟器:

adb push out/target/product/generic_x86_64/symbols/system/bin/MyCppBinderServer /data/local/tmp

adb push out/target/product/generic_x86_64/symbols/system/bin/MyCppBinderClient /data/local/tmp

1
2
3
4

接下来 adb shell 进入模拟器 shell 环境:

adb shell
cd /data/local/tmp
./MyCppBinderServer
# 从新开一个终端进入 adb shell
cd /data/local/tmp
./MyCppBinderClient
1
2
3
4
5
6

最后通过 logcat 查看执行结果:

009.Binder 驱动情景分析之服务获取与使用过程
011.Binder C++ 程序分析之主要类解析

← 009.Binder 驱动情景分析之服务获取与使用过程 011.Binder C++ 程序分析之主要类解析→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
HWC 接口分析
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式