ภาษา 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 โอเปอเรเตอร์ไบนารีเรียงจากลำดับความสำคัญต่ำสุดไปสูงสุดคือ
|| && | ^ & == != < > <= >= << >> + - * / % โอเปอเรเตอร์เอกภาคคือ + - ! ~