ภาษา AIDL

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

แพ็กเกจ

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

    package my.package;

ไฟล์ AIDL ต้องอยู่ในโครงสร้างโฟลเดอร์ที่ตรงกับแพ็กเกจเช่นเดียวกับ Java ไฟล์ที่มีแพ็กเกจ my.package ต้องอยู่ในโฟลเดอร์ my/package/

ประเภท

ในไฟล์ AIDL คุณสามารถระบุประเภทได้หลายตำแหน่ง ดูรายการประเภทที่รองรับในภาษา AIDL ได้ที่ประเภทแบ็กเอนด์ AIDL

คำอธิบายประกอบ

ภาษา AIDL หลายส่วนรองรับคำอธิบายประกอบ ดูรายการคำอธิบายประกอบและตำแหน่งที่ใช้คำอธิบายประกอบได้ที่คำอธิบายประกอบ AIDL

การนําเข้า

หากต้องการใช้ประเภทที่กําหนดไว้ในอินเทอร์เฟซอื่นๆ คุณต้องเพิ่มการพึ่งพาในระบบบิลด์ก่อน ในโมดูล Soong cc_* และ java_* ที่ใช้ไฟล์ .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 โดยปริยาย ระบบจะส่งเมธอดแบบช่องทางเดียวแบบไม่พร้อมกันและไม่สามารถแสดงผลลัพธ์ เมธอดแบบ 1 ทิศทางจากเธรดเดียวกันไปยัง Binder เดียวกันจะทํางานตามลําดับด้วย (แม้ว่าอาจอยู่ในเธรดอื่น) ดูการพูดคุยเกี่ยวกับวิธีตั้งค่าเธรดได้ที่การจัดการเธรดแบ็กเอนด์ AIDL

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

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

พาร์เซล

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

Android 10 ขึ้นไปรองรับคําจํากัดความที่แยกเป็นแพ็กเกจได้โดยตรงใน AIDL ข้อมูลที่มีการแบ่งย่อยประเภทนี้เรียกว่า Structured Parcelable ดูข้อมูลเพิ่มเติมเกี่ยวกับความสัมพันธ์ระหว่าง AIDL แบบมีโครงสร้างและแบบเสถียรในคอมไพเลอร์ AIDL และระบบบิลด์ของเราได้ที่ Structured versus stable 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 บิต (long) ดังนั้น 256 จึงถือว่าเป็น int แต่ 255 + 1 จะแสดงผลเป็น byte 0 ระบบจะตีความค่าฐาน 16 เช่น 0x3 เป็นครั้งแรกเป็นประเภทที่ไม่มีค่าแสดง (Unsigned) ที่เล็กที่สุดซึ่งเก็บค่าไว้ระหว่าง 32 บิตกับ 64 บิต จากนั้นจะตีความใหม่เป็นค่าที่ไม่มีค่าแสดง ดังนั้น 0xffffffff จึงมีค่า int -1 ตั้งแต่ Android 13 เป็นต้นไป คุณสามารถเพิ่มส่วนต่อท้าย u8 ลงในค่าคงที่ เช่น 3u8 เพื่อแสดงค่า byte ส่วนต่อท้ายนี้มีความสำคัญเพื่อให้ระบบตีความการคํานวณ เช่น 0xffu8 * 3 เป็น -3 ที่มีประเภท byte ส่วน 0xff * 3 คือ 765 ที่มีประเภท int

โอเปอเรเตอร์ที่รองรับมีความหมายตาม C++ และ Java โอเปอเรเตอร์ไบนารีมีลําดับความสำคัญจากต่ำสุดไปสูงสุดดังนี้ || && | ^ & == != < > <= >= << >> + - * / % โอเปอเรเตอร์แบบยูนาร์คือ + - ! ~