زبان AIDL

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

بسته

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

    package my.package;

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

انواع

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

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

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

واردات

برای استفاده از انواع تعریف‌شده در دیگر میان‌ها، ابتدا باید وابستگی‌ها را در سیستم ساخت اضافه کنید. در cc_* و java_* واحد Soong، که در آن‌ها از فایل‌های .aidl مستقیماً در srcs در ساخت‌های پلاتفرم Android استفاده می‌شود، می‌توانید بااستفاده از فیلد 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 مراجعه کنید.

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

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

Parcelables

برای شرح نحوه ایجاد بسته‌های داده مخصوص زیرینه، بسته‌های داده سفارشی زیرینه‌های AIDL را ببینید.

‫Android 10 و بالاتر از تعریف‌های بسته‌شدنی مستقیماً در AIDL پشتیبانی می‌کنند. این نوع parcelable، parcelable ساختاریافته نامیده می‌شود. برای کسب اطلاعات بیشتر درباره نحوه ارتباط AIDL ساختاریافته و پایدار در گردآورنده AIDL و سیستم ساخت ما، AIDL ساختاریافته دربرابر پایدار را ببینید.

برای مثال:

    package my.package;

    import my.package.Boo;

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

اتحادیه‌ها

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

    package my.package;

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

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

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

شمارشی‌ها

‫Android 11 و نسخه‌های بالاتر از اعلانات شمارشی پشتیبانی می‌کنند. برای مثال:

    package my.package;

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

اظهارنامه‌های نوع تودرتو

‫Android 13 و نسخه‌های بالاتر از بیانیه‌های نوع تودرتو پشتیبانی می‌کنند. برای مثال:

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

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

عبارت‌های ثابت

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

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

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