Ngôn ngữ AIDL

Ngôn ngữ AIDL dựa trên ngôn ngữ Java. Các tệp chỉ định một hợp đồng giao diện và nhiều loại dữ liệu và hằng số được sử dụng trong hợp đồng này.

Gói

Mỗi tệp AIDL đều bắt đầu bằng một gói tuỳ chọn tương ứng với tên gói trong nhiều phần phụ trợ. Phần khai báo gói sẽ có dạng như sau:

    package my.package;

Tương tự như Java, các tệp AIDL phải có cấu trúc thư mục khớp với gói của chúng. Các tệp có gói my.package phải nằm trong thư mục my/package/.

Loại

Trong tệp AIDL, có nhiều vị trí có thể chỉ định loại. Để biết danh sách chính xác các loại được hỗ trợ bằng ngôn ngữ AIDL, hãy xem các loại phần phụ trợ AIDL.

Chú thích

Một số phần trong chú thích hỗ trợ ngôn ngữ AIDL. Để biết danh sách chú thích và nơi có thể áp dụng chú thích, hãy xem Chú thích AIDL.

Nhập

Để sử dụng các loại được xác định trong các giao diện khác, trước tiên, bạn phải thêm các phần phụ thuộc trong hệ thống xây dựng. Trong các mô-đun Soong cc_*java_*, trong đó các tệp .aidl được sử dụng trực tiếp trong srcs trong các bản dựng nền tảng Android, bạn có thể thêm thư mục bằng cách sử dụng trường aidl: { include_dirs: ... }. Để nhập bằng aidl_interface, hãy xem tại đây.

Lệnh nhập có dạng như sau:

    import some.package.Foo;  // explicit import

Khi nhập một loại trong cùng một gói, bạn có thể bỏ qua gói đó. Tuy nhiên, việc bỏ qua gói có thể dẫn đến lỗi nhập không rõ ràng khi các loại được chỉ định mà không có gói và được đưa vào không gian tên toàn cục (thường thì tất cả các loại đều phải được đặt tên):

    import Foo;  // same as my.package.Foo

Xác định loại

Tệp AIDL thường xác định các loại được dùng làm giao diện.

Giao diện

Dưới đây là ví dụ về giao diện 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();
    }

Giao diện xác định một đối tượng bằng một loạt phương thức. Phương thức có thể là oneway (oneway void doFoo()) hoặc đồng bộ. Nếu một giao diện được xác định là oneway (oneway interface ITeleport {...}), thì tất cả phương thức trong giao diện đó đều ngầm ẩn là oneway. Các phương thức một chiều được gửi không đồng bộ và không thể trả về kết quả. Các phương thức một chiều từ cùng một luồng đến cùng một liên kết cũng thực thi tuần tự (mặc dù có thể trên các luồng khác nhau). Để thảo luận về cách thiết lập luồng, hãy xem phần Quản lý luồng trong phần phụ trợ AIDL.

Binder cho phép chia sẻ nhiều giao diện và đối tượng liên kết thông qua giao diện liên kết. Các giao diện AIDL thường sử dụng lệnh gọi lại trong lệnh gọi phương thức, chẳng hạn như với ITeleportCallback trong ví dụ trước. Bạn có thể sử dụng lại các đối tượng gọi lại giữa các lệnh gọi đến cùng một phương thức hoặc các lệnh gọi đến các phương thức khác nhau. Một cách sử dụng phổ biến khác của các loại giao diện là để các giao diện con hoặc đối tượng phiên được trả về từ các phương thức như với ITeleportSession trong ví dụ trước. Việc lồng nhau này cho phép nhiều API được đóng gói tại API hoặc dựa trên trạng thái thời gian chạy. Ví dụ: một phiên hoạt động có thể thể hiện quyền sở hữu một tài nguyên cụ thể. Khi giao diện được truyền nhiều lần hoặc trả về cho ứng dụng hoặc máy chủ mà chúng đến từ, giao diện luôn duy trì tính bằng nhau của con trỏ đối tượng liên kết cơ bản.

Các phương thức có thể không có hoặc có nhiều đối số. Đối số cho phương thức có thể là in, out hoặc inout. Để thảo luận về mức độ ảnh hưởng của điều này đến các loại đối số, hãy xem Hướng của phần phụ trợ AIDL.

Parcelable

Để biết nội dung mô tả cách tạo các gói có thể phân phối dành riêng cho phần phụ trợ, hãy xem bài viết các gói có thể phân phối tuỳ chỉnh của phần phụ trợ AIDL.

Android 10 trở lên hỗ trợ các định nghĩa có thể phân phối trực tiếp trong AIDL. Loại phân khúc có thể đóng gói này được gọi là gói có cấu trúc. Để biết thêm thông tin về mối liên hệ giữa AIDL có cấu trúc và ổn định trong trình biên dịch AIDL và hệ thống xây dựng của chúng tôi, hãy xem phần AIDL có cấu trúc so với AIDL ổn định.

Ví dụ:

    package my.package;

    import my.package.Boo;

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

Liên đoàn

Android 12 trở lên hỗ trợ khai báo liên kết được gắn thẻ. Ví dụ:

    package my.package;

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

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

Vui lòng xem bài viết Liên kết phụ trợ AIDL để biết thông tin chi tiết cụ thể về phần phụ trợ.

Liệt kê

Android 11 trở lên hỗ trợ khai báo enum. Ví dụ:

    package my.package;

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

Khai báo loại lồng nhau

Android 13 trở lên hỗ trợ khai báo loại lồng nhau. Ví dụ:

    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
    }

Hằng số

Giao diện AIDL tuỳ chỉnh, các gói có thể phân phối và các liên kết cũng có thể chứa số nguyên và hằng số chuỗi, chẳng hạn như:

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

Biểu thức hằng

Bạn có thể chỉ định hằng số AIDL, kích thước mảng và bộ đếm bằng cách sử dụng biểu thức hằng số. Biểu thức có thể sử dụng dấu ngoặc đơn để lồng các toán tử. Bạn có thể dùng các giá trị biểu thức hằng số với các giá trị tích phân hoặc giá trị số thực.

Giá trị cố định truefalse đại diện cho các giá trị boolean. Các giá trị có . nhưng không có hậu tố, chẳng hạn như 3.8, được coi là giá trị kép. Các giá trị dấu phẩy động có hậu tố f, chẳng hạn như 2.4f. Giá trị số nguyên có hậu tố l hoặc L cho biết giá trị dài 64 bit. Nếu không, các giá trị tích phân sẽ nhận được loại đã ký có giá trị nhỏ nhất giữa 8 bit (byte), 32 bit (int) và 64 bit (long). Vì vậy, 256 được coi là int, nhưng 255 + 1 sẽ tràn sang byte 0. Trước tiên, các giá trị hex, chẳng hạn như 0x3, được hiểu là kiểu chưa ký bảo toàn giá trị nhỏ nhất từ 32 bit đến 64 bit, sau đó được diễn giải lại dưới dạng giá trị chưa ký. Vì vậy, 0xffffffff có giá trị int-1. Kể từ Android 13, hậu tố u8 có thể được thêm vào các hằng số, chẳng hạn như 3u8, để biểu thị giá trị byte. Hậu tố này rất quan trọng để một phép tính, chẳng hạn như 0xffu8 * 3, được diễn giải là -3 với loại byte, trong khi 0xff * 3765 với loại int.

Các toán tử được hỗ trợ có ngữ nghĩa C++ và Java. Theo thứ tự từ mức độ ưu tiên thấp nhất đến cao nhất, các toán tử nhị phân là || && | ^ & == != < > <= >= << >> + - * / %. Toán tử một ngôi là + - ! ~.