لغة تعريف واجهة نظام Android ‏(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.

يسمح Binder بمشاركة العديد من الواجهات وعناصر Binder من خلال واجهة Binder. غالبًا ما تستخدِم واجهات AIDL وظائف الاستدعاء كجزء من طلبات تنفيذ الطريقة، مثل ITeleportCallback في المثال السابق. يمكنك إعادة استخدام مثيلات callback بين طلبات الاتصال بالطريقة نفسها أو طلبات الاتصال بأساليب مختلفة. هناك استخدام شائع آخر لأنواع الواجهات، وهو عرض الواجهات الفرعية أو عناصر الجلسة من طرق مثل with ITeleportSession في المثال السابق. يسمح هذا التداخل بتضمين واجهات برمجة تطبيقات مختلفة في إما واجهة برمجة التطبيقات أو استنادًا إلى حالة وقت التشغيل. على سبيل المثال، قد تمثّل الجلسة ملكية مورد معيّن. عند تمرير الواجهات عدة مرات أو إعادتها إلى العميل أو الخادم الذي أتت منه، تحافظ الواجهات دائمًا على تكافؤ المؤشر لعنصر الربط الأساسي.

يمكن أن تحتوي الطرق على وسيطة واحدة أو أكثر. يمكن أن تكون وسيطات الطرق in أو out أو inout. لمناقشة تأثير ذلك في أنواع الوسيطات، اطّلِع على اتجاه واجهات برمجة التطبيقات لنظام AIDL.

العناصر القابلة للتقسيم

للحصول على وصف لكيفية إنشاء مثيلات Parcelable خاصة بالخلفية، يُرجى الاطّلاع على AIDL backends custom parcelables.

يتيح الإصدار 10 من Android والإصدارات الأحدث استخدام تعريفات قابلية التجزئة مباشرةً في ملف AIDL. يُعرف هذا النوع من العناصر باسم عنصر قابل للتقسيم بشكل منظَّم. لمزيد من المعلومات عن كيفية ارتباط ملف AIDL المنظَّم وملف AIDL الثابت في مجمع ملف AIDL ونظام الإنشاء، يُرجى الاطّلاع على المقالة ملف IDEL المنظَّم في مقابل ملف IDEL الثابت.

مثلاً:

    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 للحصول على تفاصيل خاصة بالخلفية.

تعدادات

يتيح الإصدار 11 من نظام التشغيل Android والإصدارات الأحدث تعريفات التعداد. مثلاً:

    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 المخصّصة وعناصر Parcelable وعمليات الدمج أيضًا على ثوابت عددية وسلسلة، مثل:

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

التعبيرات الثابتة

يمكن تحديد ثوابت AIDL وأحجام الصفيفات وعناصر التعداد باستخدام تعبيرات ثوابت. يمكن أن تستخدم التعبيرات الأقواس لتداخل العمليات. يمكن استخدام قيم تعبير الثابتة مع القيم الصحيحة أو الكسور العشرية.

تمثّل القيم الثابتة true وfalse قيمًا منطقية. تُعتبر القيم التي تحتوي على . ولكن بدون إضافة، مثل 3.8، قيمًا مزدوجة. تحتوي قيم الأرقام الكسرية على اللاحقة f، مثل 2.4f. تشير القيمة الصحيحة التي تحتوي على اللاحقة l أو L إلى قيمة بطول 64 بت. بخلاف ذلك، تحصل قيم الأرقام الصحيحة على أصغر نوع موقَّع يحافظ على القيمة بين 8 بت (بايت) و32 بت (int) و64 بت (long). وبالتالي، يُعتبر 256 int، ولكن 255 + 1 يتجاوز الحدّ الأقصى ليصبح byte 0. يتم تفسير القيم الست عشرية، مثل 0x3، أولاً كأصغر نوع غير موقَّت يحافظ على القيمة بين 32 بت و64 بت ثم تتم إعادة تفسيرها كقيم غير موقَّتة. وبالتالي، فإنّ 0xffffffff لها القيمة int -1. بدءًا من Android 13، يمكن إضافة اللاحقة u8 إلى الثوابت، مثل 3u8، لتمثيل قيمة byte. هذه اللاحقة مهمة لتفسير عملية حسابية، مثل 0xffu8 * 3، على أنّها -3 بالنوع byte، في حين أنّ 0xff * 3 هي 765 بالنوع int.

تتضمّن عوامل التشغيل المتوافقة دلالات C++ وJava. من الأدنى إلى الأكثر أولوية، عوامل التشغيل الثنائية هي || && | ^ & == != < > <= >= << >> + - * / %. عوامل التشغيل الأحادية هي + - ! ~.