Android インターフェース定義言語(AIDL)は、IPC を考慮しなくても済むようになるツールです。インターフェースが(.aidl
ファイルで)指定されると、さまざまなビルドシステムで aidl
バイナリによって C++ または Java のバインディングが作成されます。指定されたインターフェースは、ランタイムやビット数にかかわらず複数のプロセスで使用できるようになります。
AIDL は、Android の任意のプロセス間(プラットフォーム コンポーネント間またはアプリ間)で使用できます。ただし、アプリ用 API として使用されることはありません。たとえば、SDK API をプラットフォームに実装するために AIDL を使用できますが、SDK API サーフェスに 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);
}
サーバー プロセスはインターフェースを登録して呼び出しを配信し、クライアント プロセスはそれらのインターフェースを呼び出します。多くの場合、プロセスは複数のインターフェースを参照する可能性があるため、クライアントとサーバーの両方として機能します。AIDL 言語について詳しくは、AIDL 言語をご覧ください。これらのインターフェースを使用できるさまざまなランタイムについて詳しくは、AIDL バックエンドをご覧ください。こうした型宣言は特定の言語のクラス宣言とほとんど同じですが、複数のプロセスで機能する点が異なります。
仕組み
AIDL は binder カーネル ドライバを使用して呼び出しを行います。呼び出しを行うと、1 つのメソッド識別子とすべてのオブジェクトがバッファにパッキングされ、リモート プロセスにコピーされて、binder スレッドがデータの読み取りを待機します。トランザクションのデータを受け取ると、binder スレッドはローカル プロセス内のネイティブのスタブ オブジェクトを検索します。そのクラスがデータを解凍し、ローカル インターフェース オブジェクトを呼び出します。このローカル インターフェース オブジェクトは、サーバー プロセスが作成して登録するオブジェクトです。同じプロセスと同じバックエンドで呼び出しが行われる場合は、プロキシ オブジェクトが存在しないため、呼び出しはパッキングも解凍もされずに直接行われます。
デバイス上のサービスとのインタラクション
Android には、デバイス上のサービスとのインタラクションを可能にするコマンドがいくつか用意されています。次を試します。
adb shell dumpsys --help # listing and dumping services
adb shell service --help # sending commands to services for testing