ภาษา AIDL

ภาษา AIDL อิงตามภาษา Java อย่างคร่าวๆ ไฟล์จะระบุสัญญาอินเทอร์เฟซ รวมถึงประเภทข้อมูลและค่าคงที่ต่างๆ ที่ใช้ในสัญญานี้

แพ็กเกจ

ไฟล์ AIDL ทุกไฟล์จะเริ่มต้นด้วยแพ็กเกจที่ไม่บังคับซึ่งสอดคล้องกับชื่อแพ็กเกจในแบ็กเอนด์ต่างๆ การประกาศแพ็กเกจจะมีลักษณะดังนี้

    package my.package;

ไฟล์ AIDL ต้องอยู่ในโครงสร้างโฟลเดอร์ที่ตรงกับแพ็กเกจของไฟล์เช่นเดียวกับ Java ไฟล์ที่มีแพ็กเกจ 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 โดยนัย ระบบจะส่งเมธอดแบบทางเดียวแบบไม่พร้อมกันและไม่สามารถ แสดงผลลัพธ์ได้ เมธอดแบบทางเดียวจากเธรดเดียวกันไปยัง Binder เดียวกันจะทำงานแบบอนุกรมด้วย (แม้ว่าอาจจะอยู่ในเธรดที่ต่างกัน) ดูการ อภิปรายเกี่ยวกับวิธีตั้งค่าเธรดได้ที่การจัดการเธรดของแบ็กเอนด์ AIDL

Binder ช่วยให้แชร์อินเทอร์เฟซและออบเจ็กต์ Binder จำนวนมากผ่านอินเทอร์เฟซ Binder ได้ อินเทอร์เฟซ AIDL มักใช้การเรียกกลับเป็นส่วนหนึ่งของการเรียกเมธอด เช่น ITeleportCallback ในตัวอย่างก่อนหน้า คุณสามารถนำออบเจ็กต์ Callback กลับมาใช้ใหม่ระหว่างการเรียกใช้เมธอดเดียวกันหรือการเรียกใช้เมธอดต่างๆ ได้ การใช้งานประเภทอินเทอร์เฟซอีกอย่างที่พบบ่อยคือการใช้สำหรับอินเทอร์เฟซย่อยหรือออบเจ็กต์เซสชันที่จะแสดงผลจากเมธอด เช่น ITeleportSession ในตัวอย่างก่อนหน้า การซ้อนกันนี้ช่วยให้สามารถแคปซูล API ต่างๆ ได้ที่ API หรืออิงตามสถานะรันไทม์ เช่น เซสชันอาจแสดงถึง ความเป็นเจ้าของทรัพยากรที่เฉพาะเจาะจง เมื่อมีการส่งต่ออินเทอร์เฟซหลายครั้งหรือส่งคืนไปยังไคลเอ็นต์หรือเซิร์ฟเวอร์ที่อินเทอร์เฟซนั้นมาจากที่ใด อินเทอร์เฟซจะรักษาความเท่าเทียมกันของตัวชี้ของออบเจ็กต์ Binder พื้นฐานไว้เสมอ

เมธอดอาจมีอาร์กิวเมนต์ 0 รายการหรือมากกว่า อาร์กิวเมนต์ของเมธอดอาจเป็น in, out หรือ inout ดูการอภิปรายเกี่ยวกับผลกระทบต่อประเภทอาร์กิวเมนต์ได้ที่ ทิศทางของแบ็กเอนด์ AIDL

Parcelables

ดูคำอธิบายวิธีสร้าง Parcelable เฉพาะแบ็กเอนด์ได้ที่Parcelable ที่กำหนดเองของแบ็กเอนด์ AIDL

Android 10 ขึ้นไปรองรับคำจำกัดความที่ส่งผ่านได้ ใน AIDL โดยตรง Parcelable ประเภทนี้เรียกว่า Structured Parcelable ดูข้อมูลเพิ่มเติมเกี่ยวกับความสัมพันธ์ระหว่าง AIDL ที่มีโครงสร้างและเสถียรใน คอมไพเลอร์ 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

Enums

Android 11 ขึ้นไปรองรับการประกาศ enum เช่น

    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 และ Union ยังมีค่าคงที่จำนวนเต็มและสตริงได้ด้วย เช่น

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

นิพจน์ค่าคงที่

คุณระบุค่าคงที่ AIDL, ขนาดอาร์เรย์ และตัวแจงนับได้โดยใช้ค่าคงที่ นิพจน์ นิพจน์สามารถใช้วงเล็บเพื่อซ้อนการดำเนินการได้ ค่าของนิพจน์ค่าคงที่ สามารถใช้กับค่าจำนวนเต็มหรือค่าลอยได้

ค่าบูลีนจะแสดงด้วยตัวอักษร true และ false ค่าที่มี . แต่ไม่มี คำต่อท้าย เช่น 3.8 จะถือว่าเป็นค่าแบบ Double ค่า Float มีคำต่อท้าย f เช่น 2.4f ค่าจำนวนเต็มที่มีคำต่อท้าย l หรือ L แสดงค่าแบบยาว 64 บิต มิฉะนั้น ค่าจำนวนเต็มจะได้รับ ประเภทที่มีการลงนามที่เล็กที่สุดซึ่งรักษาค่าไว้ระหว่าง 8 บิต (ไบต์), 32 บิต (int) และ 64 บิต (ยาว) ดังนั้น 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 semantics โอเปอเรเตอร์ไบนารีมีลำดับความสำคัญจากต่ำสุดไปสูงสุด ดังนี้ || && | ^ & == != < > <= >= << >> + - * / % โอเปอเรเตอร์เอกภาคคือ + - ! ~