AIDL 概述

Android 接口定義語言 (AIDL) 是一種讓用戶抽像出 IPC 的工具。給定一個接口(在.aidl文件中指定),各種構建系統使用aidl二進製文件來構建 C++ 或 Java 綁定,以便該接口可以跨進程使用,而不管那裡的運行時或位數如何。

AIDL 可以在 Android 中的任何進程之間使用:平台組件之間或應用程序之間。但是,它從未用作應用程序的 API。例如,AIDL 可用於在平台中實現 SDK API,但 SDK API 表面從不直接包含 AIDL API。有關如何在應用程序之間直接使用 AIDL 的文檔,請參閱相應的Android 開發者文檔。當在單獨更新的平台組件之間使用 AIDL 時,例如 APEX(從 Android 10 開始)或 HAL(從 Android 11 開始),必須使用稱為穩定 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 內核驅動程序進行調用。當您進行調用時,方法標識符和所有對像都被打包到緩衝區並複製到綁定線程等待讀取數據的遠程進程。一旦綁定線程接收到事務的數據,線程就會在本地進程中查找本機存根對象,並且此類解包數據並調用本地接口對象。這個本地接口對像是服務器進程創建和註冊的對象。當在同一個進程和同一個後端進行調用時,不存在代理對象,因此調用是直接的,沒有任何打包或解包。

與設備上的服務交互

Android 帶有一些命令,允許與設備上的服務進行交互。嘗試:

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