Обзор AIDL

Язык определения интерфейса Android (AIDL) — это инструмент, который позволяет пользователям абстрагироваться от IPC. Учитывая интерфейс (указанный в файле .aidl ), различные системы сборки используют двоичный файл aidl для создания привязок C++ или Java, чтобы этот интерфейс можно было использовать в процессах, независимо от времени выполнения или разрядности.

AIDL можно использовать между любыми процессами в Android: между компонентами платформы или между приложениями. Однако он никогда не используется в качестве API для приложений. Например, AIDL можно использовать для реализации API SDK на платформе, но поверхность API SDK никогда не содержит API AIDL напрямую. Документацию о том, как напрямую использовать 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 и более поздние версии поддерживают раздельные декларации. Например:

    package my.package;

    import my.package.Boo;

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

Android 11 и выше поддерживают объявления enum. Например:

    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 использует драйвер ядра связующего для выполнения вызовов. Когда вы делаете вызов, идентификатор метода и все объекты упаковываются в буфер и копируются в удаленный процесс, где поток связывателя ожидает чтения данных. Как только поток связывателя получает данные для транзакции, поток ищет собственный объект-заглушку в локальном процессе, а этот класс распаковывает данные и выполняет вызов объекта локального интерфейса. Этот объект локального интерфейса создается и регистрируется серверным процессом. Когда вызовы выполняются в одном и том же процессе и в одном и том же бэкэнде, прокси-объекты не существуют, и поэтому вызовы являются прямыми без какой-либо упаковки или распаковки.

Взаимодействие с сервисами на устройстве

Android поставляется с несколькими командами, позволяющими взаимодействовать со службами на устройстве. Пытаться:

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