AIDL hỗ trợ các chú thích cung cấp cho trình biên dịch AIDL thêm thông tin về phần tử được chú thích, điều này cũng ảnh hưởng đến mã giả lập được tạo.
Cú pháp tương tự như cú pháp của Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Ở đây, AnnotationName
là tên của chú thích và AidlEntity
là một thực thể AIDL như interface Foo
, void method()
hoặc int arg
. Chú thích được đính kèm vào thực thể theo sau.
Một số chú giải có thể có đối số được đặt bên trong dấu ngoặc đơn, như được hiển thị ở trên. Chú thích không có đối số không cần dấu ngoặc đơn. Ví dụ:
@AnnotationName AidlEntity
Các chú thích này không giống với chú thích Java, mặc dù trông rất giống nhau. Người dùng không thể xác định các chú giải AIDL tuỳ chỉnh; các chú giải đó đều được xác định trước. Một số chú thích chỉ ảnh hưởng đến một phần phụ trợ nhất định và không hoạt động trong các phần phụ trợ khác. Các tệp đính kèm này có các quy định hạn chế khác nhau về vị trí đính kèm.
Dưới đây là danh sách các chú thích AIDL được xác định trước:
Chú thích | Đã thêm vào phiên bản Android |
---|---|
nullable |
7 |
utf8InCpp |
7 |
VintfStability |
11 |
UnsupportedAppUsage |
10 |
Hide |
11 |
Backing |
11 |
NdkOnlyStableParcelable |
14 |
JavaOnlyStableParcelable |
11 |
JavaDerive |
12 |
JavaPassthrough |
12 |
FixedSize |
12 |
Descriptor |
12 |
có thể rỗng
nullable
khai báo rằng bạn không được cung cấp giá trị của thực thể được chú thích.
Bạn chỉ có thể đính kèm chú giải này vào các loại dữ liệu trả về của phương thức, tham số của phương thức và các trường có thể phân phối.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
Không thể đính kèm chú giải vào các loại dữ liệu nguyên thuỷ. Sau đây là một lỗi.
void method(in @nullable int a); // int is a primitive type
Chú thích này không hoạt động đối với phần phụ trợ Java. Lý do là trong Java, tất cả các loại không phải loại gốc đều được truyền bằng tham chiếu, có thể là null
.
Trong phần phụ trợ CPP, @nullable T
ánh xạ tới std::unique_ptr<T>
trong Android 11 trở xuống và tới std::optional<T>
trong Android 12 trở lên.
Trong phần phụ trợ NDK, @nullable T
luôn liên kết đến std::optional<T>
.
Trong phần phụ trợ Rust, @nullable T
luôn liên kết đến Option<T>
.
Đối với loại L
giống danh sách như T[]
hoặc List<T>
, @nullable L
sẽ liên kết với std::optional<std::vector<std::optional<T>>>
(hoặc std::unique_ptr<std::vector<std::unique_ptr<T>>>
trong trường hợp phần phụ trợ CPP dành cho Android 11 trở xuống).
Có một ngoại lệ đối với mối liên kết này. Khi T
là IBinder
hoặc giao diện AIDL, @nullable
sẽ không hoạt động đối với tất cả phần phụ trợ ngoại trừ Rust. Nói cách khác, cả @nullable IBinder
và IBinder
đều liên kết với android::sp<IBinder>
, vốn đã có tính chất rỗng vì đây là một con trỏ mạnh (các lượt đọc CPP vẫn thực thi tính chất rỗng, nhưng loại vẫn là android::sp<IBinder>
). Trong Rust, các loại này chỉ là nullable
nếu được chú thích bằng @nullable
. Các cookie này sẽ ánh xạ đến Option<T>
nếu được chú thích.
Kể từ Android 13, bạn có thể sử dụng @nullable(heap=true)
cho các trường có thể phân đoạn để mô hình hoá các loại đệ quy. Không thể sử dụng @nullable(heap=true)
với các tham số phương thức hoặc loại dữ liệu trả về. Khi được chú thích, trường này sẽ được liên kết với một tệp tham chiếu phân bổ vùng nhớ khối xếp std::unique_ptr<T>
trong phần phụ trợ CPP/NDK. @nullable(heap=true)
không hoạt động trong phần phụ trợ Java.
utf8InCpp
utf8InCpp
khai báo rằng String
được biểu thị ở định dạng UTF8 cho phần phụ trợ
CPP. Như tên gọi, chú thích này không hoạt động đối với các phần phụ trợ khác.
Cụ thể, String
luôn là UTF16 trong phần phụ trợ Java và UTF8 trong phần phụ trợ NDK.
Bạn có thể đính kèm chú giải này ở bất kỳ nơi nào loại String
có thể được sử dụng, bao gồm cả giá trị trả về, tham số, nội dung khai báo hằng số và trường có thể đóng gói.
Đối với phần phụ trợ CPP, @utf8InCpp String
trong AIDL liên kết đến std::string
, trong khi String
không có chú giải liên kết đến android::String16
khi sử dụng UTF16.
Xin lưu ý rằng sự tồn tại của chú thích utf8InCpp
không làm thay đổi cách truyền chuỗi qua mạng. Chuỗi luôn được truyền dưới dạng UTF16 qua mạng. Một chuỗi có chú thích utf8InCpp
sẽ được chuyển đổi thành UTF16 trước khi được truyền. Khi nhận được một chuỗi, chuỗi đó sẽ được chuyển đổi từ UTF16 sang UTF8 nếu được chú thích là utf8InCpp
.
VintfStability
VintfStability
khai báo rằng một loại do người dùng xác định (giao diện, có thể phân phối và enum) có thể được sử dụng trên hệ thống và miền của nhà cung cấp. Hãy xem phần AIDL cho HAL để biết thêm về khả năng tương tác giữa hệ thống và nhà cung cấp.
Chú giải không thay đổi chữ ký của loại, nhưng khi được đặt, thực thể của loại sẽ được đánh dấu là ổn định để có thể di chuyển giữa các nhà cung cấp và quy trình hệ thống.
Bạn chỉ có thể đính kèm chú thích vào phần khai báo loại do người dùng xác định như minh hoạ ở đây:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Khi một loại được chú thích bằng VintfStability
, mọi loại khác được tham chiếu trong loại đó cũng phải được chú thích như vậy. Trong ví dụ sau, cả Data
và IBar
đều phải được chú thích bằng VintfStability
.
@VintfStability
interface IFoo {
void doSomething(in IBar b); // references IBar
void doAnother(in Data d); // references Data
}
@VintfStability // required
interface IBar {...}
@VintfStability // required
parcelable Data {...}
Ngoài ra, bạn chỉ có thể tạo các tệp AIDL xác định các loại được chú thích bằng VintfStability
bằng cách sử dụng loại mô-đun Soong aidl_interface
, với thuộc tính stability
được đặt thành "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
UnsupportedAppUsage
Chú thích UnsupportedAppUsage
cho biết rằng loại AIDL được chú thích là một phần của giao diện không phải SDK mà các ứng dụng cũ có thể truy cập.
Hãy xem phần Các hạn chế đối với giao diện không phải SDK để biết thêm thông tin về các API ẩn.
Chú thích UnsupportedAppUsage
không ảnh hưởng đến hành vi của mã được tạo. Chú thích chỉ chú giải lớp Java đã tạo bằng chú thích Java có cùng tên.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Đây là một thao tác không có tác dụng đối với các phần phụ trợ không phải Java.
Dự phòng
Chú thích Backing
chỉ định loại bộ nhớ của loại enum AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
Trong phần phụ trợ CPP, thao tác này sẽ phát ra một lớp enum C++ thuộc loại int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Nếu bạn bỏ qua chú thích, type
sẽ được giả định là byte
, liên kết với int8_t
cho phần phụ trợ CPP.
Bạn chỉ có thể đặt đối số type
thành các loại số nguyên sau:
byte
(rộng 8 bit)int
(rộng 32 bit)long
(rộng 64 bit)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
đánh dấu một nội dung khai báo theo gói (không phải định nghĩa) là ổn định để có thể tham chiếu từ các kiểu AIDL ổn định khác. Điều này giống như JavaOnlyStableParcelable
, nhưng NdkOnlyStableParcelable
đánh dấu một nội dung khai báo có thể phân phối là ổn định cho phần phụ trợ NDK thay vì cho Java.
Cách sử dụng gói hàng này:
- Bạn phải chỉ định
ndk_header
. - Bạn phải có một thư viện NDK chỉ định gói và thư viện phải được biên dịch vào thư viện. Ví dụ: trong hệ thống xây dựng cốt lõi trên mô-đun
cc_*
, hãy sử dụngstatic_libs
hoặcshared_libs
. Đối vớiaidl_interface
, hãy thêm thư viện trongadditional_shared_libraries
trongAndroid.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
đánh dấu một nội dung khai báo có thể phân phối (không phải định nghĩa) là ổn định để có thể tham chiếu từ các loại AIDL ổn định khác.
AIDL ổn định yêu cầu tất cả các kiểu do người dùng xác định đều phải ổn định. Đối với các thành phần có thể phân đoạn, để ổn định, các trường của thành phần đó phải được mô tả rõ ràng trong tệp nguồn AIDL.
parcelable Data { // Data is a structured parcelable.
int x;
int y;
}
parcelable AnotherData { // AnotherData is also a structured parcelable
Data d; // OK, because Data is a structured parcelable
}
Nếu gói bưu kiện không có cấu trúc (hoặc vừa được khai báo), thì bạn không thể tham chiếu đến gói đó.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
cho phép bạn ghi đè quá trình kiểm tra khi gói có thể phân phối mà bạn đang tham chiếu đã có sẵn một cách an toàn trong SDK Android.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
tự động tạo các phương thức cho các loại có thể phân phối trong phần phụ trợ Java.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
Chú thích này yêu cầu các tham số bổ sung để kiểm soát nội dung cần tạo. Các tham số được hỗ trợ là:
equals=true
tạo các phương thứcequals
vàhashCode
.toString=true
tạo phương thứctoString
in tên của loại và các trường. Ví dụ:Data{number: 42, str: foo}
Mặc định Java
JavaDefault
, được thêm vào Android 13, kiểm soát việc liệu tính năng hỗ trợ phiên bản triển khai mặc định có được tạo hay không (đối với setDefaultImpl
). Tính năng hỗ trợ này không còn được tạo theo mặc định để tiết kiệm dung lượng.
JavaPassthrough
JavaPassthrough
cho phép chú thích API Java được tạo bằng một chú thích Java tuỳ ý.
Các chú giải sau trong AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
trở thành
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
trong mã Java được tạo.
Giá trị của tham số annotation
được phát trực tiếp. Trình biên dịch AIDL không xem xét giá trị của tham số. Nếu có lỗi cú pháp cấp Java, lỗi này sẽ không được trình biên dịch AIDL phát hiện mà sẽ do trình biên dịch Java phát hiện.
Bạn có thể đính kèm chú thích này vào bất kỳ thực thể AIDL nào. Chú thích này không hoạt động đối với các phần phụ trợ không phải là Java.
Kích thước cố định
FixedSize
đánh dấu một gói có cấu trúc là có kích thước cố định. Sau khi được đánh dấu, bạn sẽ không được thêm các trường mới vào đối tượng có thể phân đoạn. Tất cả các trường của đối tượng có thể phân phối cũng phải là các loại có kích thước cố định, bao gồm cả các loại gốc, enum, mảng có kích thước cố định và các đối tượng có thể phân phối khác được đánh dấu bằng FixedSize
.
Điều này không đảm bảo trên nhiều bit và không nên dựa vào hoạt động giao tiếp bit hỗn hợp.
Chỉ số mô tả
Descriptor
buộc chỉ định chỉ số mô tả giao diện của một giao diện.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
Bộ mô tả của giao diện này là android.bar.IWorld
. Nếu thiếu chú thích Descriptor
, phần mô tả sẽ là android.foo.IHello
.
Điều này rất hữu ích khi đổi tên giao diện đã được xuất bản. Việc đặt mô tả của giao diện đã đổi tên giống với mô tả của giao diện trước khi đổi tên cho phép hai giao diện giao tiếp với nhau.
@hide trong bình luận
Trình biên dịch AIDL nhận ra @hide
trong các nhận xét và chuyển nó đến đầu ra Java để Metalava nhận. Chú thích này đảm bảo rằng hệ thống xây dựng Android biết rằng các API AIDL không phải là API SDK.
@đã ngừng hoạt động trong nhận xét
Trình biên dịch AIDL nhận ra @deprecated
trong các nhận xét là một thẻ để xác định một thực thể AIDL không còn được sử dụng nữa.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Mỗi phần phụ trợ đánh dấu các thực thể không dùng nữa bằng một chú thích hoặc thuộc tính dành riêng cho phần phụ trợ để cảnh báo mã ứng dụng nếu mã đó tham chiếu đến các thực thể không dùng nữa. Ví dụ: chú thích @Deprecated
và thẻ @deprecated
được đính kèm vào mã do Java tạo.