AIDL Overview

The Android Interface Definition Language (AIDL) is a tool that lets users abstract away IPC. Given an interface (specified in a .aidl file), various build systems use the aidl binary to construct C++ or Java bindings so that this interface can be used across processes, regardless of the runtime or bitness there.

AIDL can be used between any process in Android: between platform components or between apps. However, it is never used as an API for apps. AIDL may be used to implement an SDK API in the platform, for instance, but the SDK API surface never contains AIDL APIs directly. For documentation about how to use AIDL between apps directly, see corresponding Android developers documentation. When AIDL is used between platform components that are updated separately, such as APEXes (starting in Android 10) or HALs (starting in Android 11), the versioning system known as Stable AIDL must be used.


Here is an example AIDL interface:

    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 and higher support parcelable declarations. For example:

    package my.package;

    import my.package.Boo;

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

Android 11 and higher support enum declarations. For example:

    package my.package;

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

Android 12 and higher support union declarations. For example:

    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 experimental) and higher support nested type declarations. For example:

    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

A server process registers an interface and serves calls to it, and a client process makes calls to those interfaces. In many cases, a process acts as both a client and a server since it may be referencing multiple interfaces. For more details about the various runtimes available to use these interfaces, see AIDL backends. These type declarations are exactly like a class declaration in a given language, but they work across processes.

How it works

AIDL uses the binder kernel driver to make calls. When you make a call, a method identifier and all of the objects are packed onto a buffer and copied to a remote process where a binder thread waits to read the data. Once a binder thread receives data for a transaction, the thread looks up a native stub object in the local process, and this class unpacks the data and makes a call on a local interface object. This local interface object is the one a server process creates and registers. When calls are made in the same process and the same backend, no proxy objects exist, and so calls are direct without any packing or unpacking.

Interacting with services on the device

Android comes with a few commands to allow interacting with services on the device. Try:

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