这是一个 Binder 相关的系列教程,持续更新中:
- 学习 Binder 的预备知识
- Binder 基本原理
- Binder 程序示例之 C 语言篇
- Binder 服务注册过程情景分析之C语言篇
- Binder 服务获取与使用过程情景分析之C语言篇
- Binder 驱动情景分析之 ServiceManager 启动过程
- Binder 驱动情景分析之服务注册过程
- Binder 驱动情景分析之服务获取与使用过程
- Binder C++ 程序示例
- Binder 程序示例之 aidl-cpp 篇【本文】
- Binder C++ 程序分析之主要类解析
- Binder 服务注册过程情景分析之 C++ 篇
- Binder 服务获取与使用过程情景分析之 C++ 篇
- Binder 程序示例之 Java 篇
- Binder Java 程序分析之主要类解析
- Binder 服务注册过程情景分析之 Java 篇
- Binder 服务获取与使用过程情景分析之 Java 篇
- Binder 多线程分析
- Binder 匿名服务分析
- Binder 死亡通知机制
- Binder 相关疑难 bug 解析
- Binder 面试题解析
上文中手动去写这些模板代码还是有点繁琐,google 提供了 aidl-cpp 工具来简化我们的开发工作,接下来我们就来看看如何使用 aidl-cpp:
本文源码可以在 github.com/yuandaimaah… 下载到
定义协议文件
在 device/jelly/rice14/
目录下创建如下的目录与文件:
AIDLCppDemo
├── Android.bp
├── com
│ └── yuandaima
│ └── IHello.aidl
├── HelloClient.cpp
└── HelloServer.cpp
其中 IHello.aidl 就是我们定义的协议文件:
package com.yuandaima;
interface IHello
{
void hello();
int sum(int x, int y);
}
定义了两个远程调用函数 hello 和 sum。
接着我们使用 aidl-cpp 命令生成必要的 cpp 代码:
aidl-cpp com/yuandaima/IHello.aidl ./ ./IHello.cpp
生成如下的代码:
AIDLCppDemo
├── Android.bp
├── com
│ └── yuandaima
│ ├── BnHello.h
│ ├── BpHello.h
│ ├── IHello.aidl
│ └── IHello.h
├── HelloClient.cpp
├── HelloServer.cpp
└── IHello.cpp
服务端实现
接着我们来实现我们的服务端 HelloServer.cpp:
#define LOG_TAG "aidl_cpp"
#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "com/yuandaima/IHello.h"
#include "com/yuandaima/BnHello.h"
using namespace android;
class IHelloServer : public com::yuandaima::BnHello
{
public:
binder::Status hello()
{
ALOGI("hello");
return binder::Status();
}
binder::Status sum(int32_t v1, int32_t v2, int32_t *_aidl_return) override
{
ALOGI("server: sum: %d + %d", v1, v2);
*_aidl_return = v1 + v2;
return binder::Status();
}
};
int main(int argc, char const *argv[])
{
defaultServiceManager()->addService(String16("IHello"), new IHelloServer());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
具体实现和我们前文中介绍的基本一致。
客户端实现
接着我们来实现客户端代码 HelloClient.cpp:
#define LOG_TAG "aidl_cpp"
#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "com/yuandaima/IHello.h"
#include "com/yuandaima/BnHello.h"
using namespace android;
int main(int argc, char const *argv[])
{
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("IHello"));
sp<com::yuandaima::IHello> hello = interface_cast<com::yuandaima::IHello>(binder);
hello->hello();
int ret = 0;
hello->sum(1, 2, &ret);
return 0;
}
具体实现和我们前文中介绍的基本一致。
编译与运行
接着我们编写 Android.bp 文件:
cc_defaults {
name: "BinderCppAidlDemoflags",
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
"-Wno-unused-parameter",
"-Wno-unused-variable",
"-Wno-incompatible-pointer-types",
"-Wno-sign-compare",
],
product_variables: {
binder32bit: {
cflags: ["-DBINDER_IPC_32BIT=1"],
},
},
}
cc_binary {
name: "IHelloClient",
defaults: ["BinderCppAidlDemoflags"],
srcs: ["HelloClient.cpp","IHello.cpp"],
shared_libs: [
"liblog",
"libcutils",
"libandroidfw",
"libutils",
"libbinder",
],
}
cc_binary {
name: "IHelloServer",
defaults: ["BinderCppAidlDemoflags"],
srcs: ["HelloServer.cpp","IHello.cpp"],
shared_libs: [
"liblog",
"libcutils",
"libandroidfw",
"libutils",
"libbinder",
],
}
最后编译运行:
# 启动模拟器
source build/envsetup.sh
lunch rice14-eng #选择合适的 product 版本
# 在 device/jelly/rice14/AIDLCppDemo 目录下
mm #模块编译
# push 可执行文件到设备上
adb push out/target/product/rice14/system/bin/IHellServer /data/local/tmp
adb push out/target/product/rice14/system/bin/IHellClient /data/local/tmp
接着执行可执行文件:
adb shell
cd /data/local/tmp
./IHelloServer &
./IHelloClient
接着查看 log:
logcat | grep "aidl_cpp"
至此我们的示例程序就完成了。
关于
我叫阿豪,2015 年本科毕业于国防科技大学指挥自动化专业,毕业后,从事信息化装备的研发工作。主要研究方向为 Android Framework 与 Linux Kernel,2023年春节后开始做 Android Framework 相关的技术分享。
如果你对 Framework 感兴趣或者正在学习 Framework,可以参考我总结的Android Framework 学习路线指南,也可关注我的微信公众号,我会在公众号上持续分享我的经验,帮助正在学习的你少走一些弯路。学习过程中如果你有疑问或者你的经验想要分享给大家可以添加我的微信,我拉你进技术交流群。