Panoramica AIDL

L'Android Interface Definition Language (AIDL) è uno strumento che consente agli utenti di astrarre l'IPC. Data un'interfaccia (specificata in un file .aidl ), vari sistemi di build utilizzano il binario aidl per costruire collegamenti C++ o Java in modo che questa interfaccia possa essere utilizzata tra i processi, indipendentemente dal runtime o dal bit presente.

AIDL può essere utilizzato tra qualsiasi processo in Android: tra i componenti della piattaforma o tra le app. Tuttavia, non viene mai utilizzato come API per le app. AIDL può essere utilizzato per implementare un'API SDK nella piattaforma, ad esempio, ma la superficie dell'API SDK non contiene mai API AIDL direttamente. Per la documentazione su come utilizzare AIDL direttamente tra le app, vedere la documentazione per sviluppatori Android corrispondente. Quando AIDL viene utilizzato tra i componenti della piattaforma aggiornati separatamente, come APEX (a partire da Android 10) o HAL (a partire da Android 11), è necessario utilizzare il sistema di controllo delle versioni noto come AIDL stabile .

Esempio

Ecco un esempio di interfaccia 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 e versioni successive supportano le dichiarazioni parcelable. Per esempio:

    package my.package;

    import my.package.Boo;

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

Android 11 e versioni successive supportano le dichiarazioni enum. Per esempio:

    package my.package;

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

Android 12 e versioni successive supportano le dichiarazioni sindacali. Per esempio:

    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 sperimentale) e versioni successive supportano le dichiarazioni di tipo nidificato. Per esempio:

    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
    }

Un processo server registra un'interfaccia e serve le chiamate ad essa e un processo client effettua chiamate a tali interfacce. In molti casi, un processo funge sia da client che da server poiché potrebbe fare riferimento a più interfacce. Per maggiori dettagli sui vari runtime disponibili per utilizzare queste interfacce, vedere backend AIDL . Queste dichiarazioni di tipo sono esattamente come una dichiarazione di classe in una determinata lingua, ma funzionano su tutti i processi.

Come funziona

AIDL utilizza il driver del kernel del raccoglitore per effettuare chiamate. Quando si effettua una chiamata, un identificatore di metodo e tutti gli oggetti vengono compressi in un buffer e copiati in un processo remoto in cui un thread raccoglitore attende per leggere i dati. Una volta che un thread raccoglitore riceve i dati per una transazione, il thread cerca un oggetto stub nativo nel processo locale e questa classe decomprime i dati ed effettua una chiamata su un oggetto dell'interfaccia locale. Questo oggetto di interfaccia locale è quello che un processo server crea e registra. Quando le chiamate vengono effettuate nello stesso processo e nello stesso back-end, non esistono oggetti proxy e quindi le chiamate sono dirette senza alcun imballaggio o decompressione.

Interazione con i servizi sul dispositivo

Android viene fornito con alcuni comandi per consentire l'interazione con i servizi sul dispositivo. Provare:

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