Google 致力于为黑人社区推动种族平等。查看具体举措

AIDL 概览

Android 接口定义语言 (AIDL) 是一款可供用户用来抽象化 IPC 的工具。以在 .aidl 文件中指定的接口为例,各种构建系统都会使用 aidl 二进制文件构造 C++ 或 Java 绑定,以便跨进程使用该接口(无论其运行时环境或位数如何)。

AIDL 可以在 Android 中的任何进程之间使用:在平台组件之间使用或在应用之间使用均可。但是,AIDL 绝不能用作应用的 API。例如,可以使用 AIDL 在平台中实现 SDK API,但 SDK API Surface 绝不能直接包含 AIDL API。如需获取有关如何在应用之间直接使用 AIDL 的文档,请参阅相应的 Android 开发者文档。在 APEX(从 Android 10 开始)或 HAL(从 Android 11 开始)等单独更新的平台组件之间使用 AIDL 时,必须使用称为稳定的 AIDL 的版本控制系统。

示例

以下是一个 AIDL 接口示例:

    package my.package;

    import my.package.Baz; // defined elsewhere

    interface IFoo {
        void doFoo(Baz baz); // synchronous method
        oneway void doFoo(int a); // async method
    }

Android 10 及更高版本支持 parcelable 声明。例如:

    package my.package;

    import my.package.Boo;

    parcelable Baz {
        @utf8InCpp String name = "baz";
        Boo boo;
    }

Android 11 及更高版本支持枚举声明。例如:

    package my.package;

    enum Boo {
        A = 1 * 4,
        B = 3,
    }

Android 12 及更高版本支持联合声明。例如:

    package my.package;

    import my.package.FooSettings;
    import my.package.BarSettings;

    union Settings {
        FooSettings fooSettings;
        BarSettings barSettings;
        @utf8InCpp String str;
        int number;
    }

Android T(AOSP 实验版)及更高版本支持嵌套类型声明。 例如:

    package my.package;

    import my.package.Baz;

    interface IFoo {
        void doFoo(Baz.Nested nested);  // defined in my/package/Baz.aidl
        void doBar(Bar bar);            // defined below

        parcelable Bar { ... }          // nested type definition
    }

服务器进程注册接口并提供对它的调用,客户端进程则调用这些接口。在许多情况下,进程既是客户端又是服务器,因为它可能会引用多个接口。如需详细了解可供您用来使用这些接口的各种运行时环境,请参阅 AIDL 后端。这些类型声明与给定语言中的类声明完全相同,但可以跨进程工作。

工作原理

AIDL 使用 Binder 内核驱动程序进行调用。当您发出调用时,系统会将方法标识符和所有对象打包到某个缓冲区中,然后将其复制到某个远程进程,该进程中有一个 Binder 线程正在等待读取数据。Binder 线程收到某个事务的数据后,该线程会在本地进程中查找原生桩对象,然后此类会解压缩数据并调用本地接口对象。此本地接口对象正是服务器进程所创建和注册的对象。当在同一进程和同一后端中进行调用时,不存在代理对象,因此直接调用即可,无需执行任何打包或解压缩操作。

与设备上的服务互动

Android 具有一些命令,可供您用来与设备上的服务互动。请尝试输入:

    adb shell dumpsys --help # listing and dumping services
    adb shell service --help # sending commands to services for testing