Java 和 C++ 之间的 AIDL 接口

Sri*_*vas 4 c++ java interface aidl

我是 AIDL 界面的新手。我想在使用 gradle 构建的 Java(应用程序层)和使用 cmake 构建的 C++(本机层)之间实现 AIDL 接口。我需要使用 AIDL 接口在这两个进程之间传递大量数据。我能够在应用程序层实现 .aidl 文件并能够创建服务。我需要在本机层实现aidl客户端并需要传递数据。任何人都可以建议我如何实现要构建的 AIDL cmake。

f9c*_*534 6

要获取aidl-cpp二进制文件,您必须使用此处的说明和此处的前几条说明来设置 AOSP 源代码。设置构建环境后,您可以使用make aidl-cpp. 然后可以在例如 中找到该二进制文件out/host/linux-x86/bin/aidl-cpp。您只需执行一次此操作,在获得二进制文件后,您不再需要 AOSP 代码(尽管最好有代码可以快速搜索示例)。

关于 CMake 部分,正如评论中所讨论的,一旦构建了aidl-cpp二进制文件,就可以使用 CMake 命令add_custom_target来生成代码。

aidl-cpp命令提供以下说明:

usage: aidl-cpp INPUT_FILE HEADER_DIR OUTPUT_FILE

OPTIONS:
   -I<DIR>   search path for import statements
   -d<FILE>  generate dependency file
   -ninja    generate dependency file in a format ninja understands

INPUT_FILE:
   an aidl interface file
HEADER_DIR:
   empty directory to put generated headers
OUTPUT_FILE:
   path to write generated .cpp code
Run Code Online (Sandbox Code Playgroud)

因此,当您从 cmake 调用该命令时,您必须提供 AIDL,然后提供生成的头文件应存储的目录,以及生成的 cpp 文件应存储的名称。例如aidl-cpp ISomeInterface.aidl ./generated-headers ./generated-cpp/ISomeInterface.cpp。如果您想使用自定义数据类型(请参阅本答案的最后一部分),您还必须传递标志-I以指向自定义数据类型的声明。

用 C++ 创建活页夹客户端

使用 生成头文件和 cpp 文件后aidl-cpp,您就可以从 C++ 连接到您的服务。以下是 AOSP 源代码中的示例:

  • 有一个名为 .AIDL 的文件IDropboxManagerService

  • AIDL 定义的接口的实现方式与DropboxManagerServiceJava 中一样。

  • 此处从 C++ 调用该服务:

    • <com/android/internal/os/IDropBoxManagerService.h请注意文件开头的包含(链接)。aidl-cpp这是从 AIDL 文件生成的头文件。

    • 默认服务管理器用于查找名为的服务"dropbox"

      defaultServiceManager()->getService(android::String16("dropbox"))
      
      Run Code Online (Sandbox Code Playgroud)
    • 结果被getService转换为生成的头文件中定义的接口:

      sp<IDropBoxManagerService> service = interface_cast<IDropBoxManagerService>(...)
      
      Run Code Online (Sandbox Code Playgroud)
    • service对象现在拥有一个代理对象,您可以在该代理对象上调用 AIDL 中定义的方法。然后,代理对象将通过 Binder 将这些调用转发到 Java 服务(这是在 生成的 cpp 文件中实现的aidl-cpp)。

      例如,AIDL定义了一个方法void add(in DropBoxManager.Entry entry);。C++ 代码使用Status status = service->add(entry);. 您可以通过 查询交易结果status.isOk()

发送自定义数据类型

关于数据类型,您可以在此处找到 C++ 类型到 Java 类型的映射表。

如果要发送自定义对象,则必须定义一个 C++ 类和一个 Java 类,它们都实现该Parcelable接口。该接口需要在C++中实现两个方法writeToParcel/ ,在Java中实现/ 。您必须在每一端提供匹配的实现,以便在 C++ 对象上调用eg 生成可以在Java 端读取的平面二进制编码。readFromParcelwriteToParcelcreateFromParcelwriteToParcelreadFromParcel

您还必须提供一个 AIDL 文件,该文件指向使用该cpp_header指令的自定义对象的标头。请参见以下示例:

  • DropBoxManagerService上一节的示例中,我们看到了一个类型为 的对象Entry

  • 在AIDL中,一个parcelable在这里被声明。请注意,这没有定义任何实现细节,它只是声明存在一个具有此名称的类。它还指向 C++ 头文件,该头文件将包含在aidl-cpp.

  • 我们在上一个示例中查看的AIDL在此DropBoxManagerService导入了 Parcelable 的 AIDL 。这允许在 AIDL 方法声明中使用此数据类型。

基于这些步骤,EntryC++中定义的类可以从C++发送到Java。当将Entry对象传递给 C++ 中的代理对象时,生成的 cppaidl-cpp将使用writeToParcel为该类实现的函数Entry将类序列化为平面二进制编码。在 Java 端,接收编码并Entry根据编码构造 Java 对象。