زبان ایدل

زبان AIDL تا حدودی مبتنی بر زبان جاوا است. فایل‌ها یک قرارداد رابط و انواع مختلف داده و ثابت‌های مورد استفاده در این قرارداد را مشخص می‌کنند.

بسته

هر فایل AIDL با یک بسته اختیاری شروع می‌شود که با نام بسته‌ها در backend های مختلف مطابقت دارد. تعریف یک بسته به این شکل است:

    package my.package;

مشابه جاوا، فایل‌های AIDL باید در ساختار پوشه‌ای مطابق با بسته خود باشند. فایل‌هایی که دارای package my.package هستند باید در پوشه my/package/ باشند.

انواع

در فایل‌های AIDL، مکان‌های زیادی وجود دارد که می‌توان انواع را مشخص کرد. برای فهرست دقیقی از انواعی که در زبان AIDL پشتیبانی می‌شوند، به انواع backends AIDL مراجعه کنید.

حاشیه‌نویسی‌ها

چندین بخش از زبان AIDL از حاشیه‌نویسی‌ها پشتیبانی می‌کنند. برای مشاهده‌ی فهرستی از حاشیه‌نویسی‌ها و محل اعمال آنها، به بخش حاشیه‌نویسی‌های AIDL مراجعه کنید.

واردات

برای استفاده از انواع تعریف‌شده در رابط‌های دیگر، ابتدا باید وابستگی‌ها را در سیستم ساخت اضافه کنید. در ماژول‌های cc_* و java_* Soong، که در آن‌ها فایل‌های .aidl مستقیماً تحت srcs در ساخت‌های پلتفرم اندروید استفاده می‌شوند، می‌توانید دایرکتوری‌ها را با استفاده از فیلد aidl: { include_dirs: ... } اضافه کنید. برای وارد کردن با استفاده از aidl_interface ، به اینجا مراجعه کنید.

یک ایمپورت به این شکل است:

    import some.package.Foo;  // explicit import

هنگام وارد کردن یک نوع در همان بسته، می‌توان بسته را حذف کرد. اگرچه، حذف بسته می‌تواند منجر به خطاهای مبهم در وارد کردن شود، زمانی که انواع بدون بسته مشخص شده و در فضای نام سراسری قرار می‌گیرند (به طور کلی همه نوع‌ها باید فضای نام داشته باشند):

    import Foo;  // same as my.package.Foo

تعریف انواع

فایل‌های AIDL عموماً انواعی را تعریف می‌کنند که به عنوان رابط استفاده می‌شوند.

رابط‌ها

در اینجا یک مثال از رابط AIDL آورده شده است:

    interface ITeleport {
        // Location defined elsewhere
        void teleport(Location baz, float speed);
        String getName();

        // ITeleportCallback defined elsewhere
        void methodWithCallback(ITeleportCallback callback);

        // ITeleportSession defined elsewhere
        ITeleportSession getASubInterface();
    }

یک رابط، یک شیء را با مجموعه‌ای از متدها تعریف می‌کند. متدها می‌توانند oneway ( oneway void doFoo() ) یا همزمان باشند. اگر یک رابط به صورت oneway ( oneway interface ITeleport {...} ) تعریف شود، تمام متدهای موجود در آن به طور ضمنی oneway هستند. متدهای یک‌طرفه به صورت ناهمزمان ارسال می‌شوند و نمی‌توانند نتیجه‌ای را برگردانند. متدهای یک‌طرفه از یک نخ به یک اتصال‌دهنده نیز به صورت سریالی اجرا می‌شوند (هرچند به طور بالقوه روی نخ‌های مختلف). برای بحث در مورد نحوه راه‌اندازی نخ‌ها، به مدیریت نخ‌های AIDL backends مراجعه کنید.

رابط (Binder) امکان اشتراک‌گذاری بسیاری از رابط‌ها و اشیاء رابط را از طریق رابط‌های رابط فراهم می‌کند. رابط‌های AIDL اغلب از فراخوانی‌های برگشتی به عنوان بخشی از فراخوانی‌های متد استفاده می‌کنند، مانند ITeleportCallback در مثال قبلی. می‌توانید از اشیاء برگشتی بین فراخوانی‌های یک متد یا فراخوانی‌های متدهای مختلف دوباره استفاده کنید. یکی دیگر از کاربردهای رایج انواع رابط، برای رابط‌های فرعی یا اشیاء جلسه‌ای است که از متدهایی مانند ITeleportSession در مثال قبلی بازگردانده می‌شوند. این تودرتوسازی اجازه می‌دهد تا APIهای مختلف در API یا بر اساس وضعیت زمان اجرا کپسوله شوند. به عنوان مثال، یک جلسه ممکن است نشان‌دهنده مالکیت یک منبع خاص باشد. هنگامی که رابط‌ها چندین بار منتقل می‌شوند یا به کلاینت یا سروری که از آن آمده‌اند بازگردانده می‌شوند، همیشه برابری اشاره‌گر شیء رابط زیرین را حفظ می‌کنند.

متدها می‌توانند صفر یا چند آرگومان داشته باشند. آرگومان‌های متدها می‌توانند in ، out یا inout باشند. برای بحث در مورد چگونگی تأثیر این موضوع بر انواع آرگومان‌ها، به بخش جهت‌داری بک‌اندهای AIDL مراجعه کنید.

بسته‌های قابل بسته‌بندی

برای توضیح نحوه ایجاد parcelableهای مخصوص backend، به بخش AIDL در backendهای سفارشی parcelables مراجعه کنید .

اندروید ۱۰ و بالاتر از تعاریف parcelable مستقیماً در AIDL پشتیبانی می‌کنند. این نوع parcelable، parcelable ساختاریافته نامیده می‌شود. برای اطلاعات بیشتر در مورد چگونگی ارتباط AIDL ساختاریافته و پایدار در کامپایلر AIDL و سیستم ساخت ما، به بخش AIDL ساختاریافته در مقابل پایدار مراجعه کنید.

برای مثال:

    package my.package;

    import my.package.Boo;

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

اتحادیه‌ها

اندروید ۱۲ و بالاتر از اعلان‌های اتحادیه برچسب‌گذاری شده پشتیبانی می‌کند. برای مثال:

    package my.package;

    import my.package.FooSettings;
    import my.package.BarSettings;

    union Settings {
        FooSettings fooSettings;
        BarSettings barSettings;
        @utf8InCpp String str;
        int number;
    }

برای جزئیات مربوط به backend به AIDL Backends Unions مراجعه کنید.

انوم‌ها

اندروید ۱۱ و بالاتر از تعریف enum پشتیبانی می‌کند. برای مثال:

    package my.package;

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

اعلان‌های نوع تو در تو

اندروید ۱۳ و بالاتر از اعلان‌های نوع تو در تو پشتیبانی می‌کنند. برای مثال:

    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 سفارشی، parcelableها و unionها می‌توانند شامل ثابت‌های عدد صحیح و رشته‌ای نیز باشند، مانند:

    const @utf8InCpp String HAPPY = ":)";
    const String SAD = ":(";
    const byte BYTE_ME = 1;
    const int ANSWER = 6 * 7;

عبارات ثابت

ثابت‌های AIDL، اندازه‌های آرایه و شمارنده‌ها را می‌توان با استفاده از عبارات ثابت مشخص کرد. عبارات می‌توانند از پرانتز برای تودرتو کردن عملیات استفاده کنند. مقادیر عبارات ثابت را می‌توان با مقادیر صحیح یا اعشاری استفاده کرد.

مقادیر true و false ، مقادیر بولی را نشان می‌دهند. مقادیری که دارای علامت . هستند اما پسوند ندارند، مانند 3.8 ، به عنوان مقادیر double در نظر گرفته می‌شوند. مقادیر اعشاری دارای پسوند f هستند، مانند 2.4f . یک مقدار صحیح با پسوند l یا L نشان دهنده یک مقدار با طول ۶۴ بیتی است. در غیر این صورت، مقادیر صحیح کوچکترین نوع علامت‌دار با حفظ مقدار بین ۸ بیت (بایت)، ۳۲ بیت (اینتگرال) و ۶۴ بیت (بلند) را دریافت می‌کنند. بنابراین 256 به عنوان یک int در نظر گرفته می‌شود، اما 255 + 1 به عنوان byte 0 سرریز می‌شود. مقادیر هگز، مانند 0x3 ، ابتدا به عنوان کوچکترین نوع بدون علامت با حفظ مقدار بین ۳۲ بیت و ۶۴ بیت تفسیر می‌شوند و سپس به عنوان مقادیر بدون علامت دوباره تفسیر می‌شوند. بنابراین، 0xffffffff مقدار int -1 را دارد. از اندروید ۱۳ به بعد، پسوند u8 می‌تواند به ثابت‌هایی مانند 3u8 اضافه شود تا مقدار byte را نشان دهد. این پسوند مهم است زیرا محاسبه‌ای مانند 0xffu8 * 3 به صورت -3 با نوع byte تفسیر می‌شود در حالی که 0xff * 3 برابر با 765 با نوع int است.

عملگرهای پشتیبانی‌شده دارای معانی C++ و جاوا هستند. به ترتیب از پایین‌ترین به بالاترین اولویت، عملگرهای دودویی عبارتند از || && | ^ & == != < > <= >= << >> + - * / % . عملگرهای یگانی عبارتند از + - ! ~ .