AIDL은 주석이 지정된 요소에 관한 추가 정보를 AIDL 컴파일러에 제공하는 주석을 지원하며 이는 생성된 스텁 코드에도 영향을 줍니다.
구문은 다음과 같이 자바 구문과 유사합니다.
@AnnotationName(argument1=value, argument2=value) AidlEntity
여기서 AnnotationName
은 주석의 이름이며 AidlEntity
는 interface Foo
, void method()
, int arg
와 같은 AIDL 항목입니다. 주석은 그 뒤에 오는 항목에 연결됩니다.
일부 주석에서는 위와 같이 괄호 안에 인수를 설정할 수 있습니다. 인수가 없는 주석에는 괄호가 필요하지 않습니다. 예를 들면 다음과 같습니다.
@AnnotationName AidlEntity
이러한 주석은 자바 주석과 매우 비슷해 보이지만 동일하지는 않습니다. 사용자는 맞춤 AIDL 주석을 정의할 수 없습니다. 주석은 모두 미리 정의되어 있습니다. 일부 주석은 특정 백엔드에만 영향을 주며 다른 백엔드에서는 작동하지 않습니다. 주석이 어떤 항목에 연결될 수 있는지에 대한 제한사항은 주석마다 다릅니다.
다음은 사전 정의된 AIDL 주석의 목록입니다.
주석 | Android 버전에 추가됨 |
---|---|
nullable |
7 |
utf8InCpp |
7 |
VintfStability |
11 |
UnsupportedAppUsage |
10 |
Hide |
11 |
Backing |
11 |
JavaOnlyStableParcelable |
11 |
JavaDerive |
12 |
JavaPassthrough |
12 |
FixedSize |
12 |
Descriptor |
12 |
nullable
nullable
은 주석이 지정된 항목의 값이 제공되지 않을 수 있음을 선언합니다.
이 주석은 메서드 반환 유형, 메서드 매개변수 및 parcelable 필드에만 연결될 수 있습니다.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
주석은 기본 유형에 연결될 수 없습니다. 다음은 오류입니다.
void method(in @nullable int a); // int is a primitive type
이 주석은 자바 백엔드에는 작동하지 않습니다. 이는 자바에서 기본 유형이 아닌 모든 유형이 참조로 전달되며 null
일 수 있기 때문입니다.
CPP 백엔드에서 @nullable T
는 Android 11 및 이전 버전에서는 std::unique_ptr<T>
에 매핑되고 Android 12 및 이후 버전에서는 std::optional<T>
에 매핑됩니다.
NDK 백엔드에서 @nullable T
는 항상 std::optional<T>
에 매핑됩니다.
T[]
또는 List<T>
와 같이 목록과 유사한 유형 L
의 경우 @nullable L
은 std::optional<std::vector<std::optional<T>>>
(또는 Android 11 이하용 CPP 백엔드의 경우 std::unique_ptr<std::vector<std::unique_ptr<T>>>
)에 매핑됩니다.
이 매핑에는 예외가 있습니다. T
가 IBinder
또는 AIDL 인터페이스일 때 @nullable
은 작동하지 않습니다. 즉, @nullable IBinder
와 IBinder
는 모두 android::sp<IBinder>
(강력한 포인터이기 때문에 이미 null을 허용할 수 있음)에 동일하게 매핑됩니다(CPP 읽기는 여전히 null 허용 여부를 적용하지만 형식은 android::sp<IBinder>
입니다).
Android 13부터는 @nullable(heap=true)
를 parcelable 필드에 사용하여 재귀 유형을 모델링할 수 있습니다. @nullable(heap=true)
는 메서드 매개변수 또는 반환 유형과 함께 사용할 수 없습니다. 이 주석을 달면 필드가 CPP/NDK 백엔드의 힙 할당 참조 std::unique_ptr<T>
에 매핑됩니다. @nullable(heap=true)
는 자바 백엔드에서 작동하지 않습니다.
utf8InCpp
utf8InCpp
는 String
이 CPP 백엔드에 관해 UTF8 형식으로 표시된다는 것을 선언합니다. 이름에서 알 수 있듯이 이 주석은 다른 백엔드에서는 작동하지 않습니다.
특히 String
은 자바 백엔드에서 항상 UTF16이며 NDK 백엔드에서는 UTF8입니다.
반환 값, 매개변수, 상수 선언, parcelable 필드 등 String
유형을 사용할 수 있는 곳이면 어디에나 이 주석을 지정할 수 있습니다.
CPP 백엔드의 경우 AIDL의 @utf8InCpp String
은 std::string
에 매핑되지만 주석이 없는 String
은 UTF16이 사용되는 android::String16
에 매핑됩니다.
utf8InCpp
주석이 있다고 해서 문자열이 유선을 통해 전송되는 방식이 변경되지는 않습니다. 문자열은 항상 유선을 통해 UTF16으로 전송됩니다. utf8InCpp
주석이 지정된 문자열은 전송되기 전에 UTF16으로 변환됩니다. 문자열이 수신되었을 때 이 문자열이 utf8InCpp
로 주석이 지정되었다면 UTF16에서 UTF8로 변환됩니다.
VintfStability
VintfStability
는 사용자 정의 유형(인터페이스, parcelable 및 enum)을 시스템 및 공급업체 도메인 전체에서 사용할 수 있음을 선언합니다. 시스템-공급업체 상호 운용성에 관한 자세한 내용은 HAL용 AIDL을 참조하세요.
주석이 유형의 서명을 변경하지 않지만 설정될 경우 유형의 인스턴스는 공급업체 및 시스템 프로세스 전체에 걸쳐 이동할 수 있도록 안정적인 것으로 표시됩니다.
주석은 아래와 같이 사용자 정의 유형 선언에만 연결될 수 있습니다.
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
유형이 VintfStability
로 주석이 지정될 때 유형에서 참조되는 다른 유형도 이와 같이 주석이 지정되어야 합니다. 아래 예에서 Data
와 IBar
는 모두 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 {...}
또한 VintfStability
로 주석이 지정된 유형을 정의하는 AIDL 파일은 stability
속성이 "vintf"
로 설정된 aidl_interface
Soong 모듈 유형을 사용해서만 빌드할 수 있습니다.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
UnsupportedAppUsage
UnsupportedAppUsage
주석은 주석이 지정된 AIDL 유형이 레거시 앱에서 액세스할 수 있는 비SDK 인터페이스의 일부임을 나타냅니다.
숨겨진 API에 관한 자세한 내용은 비SDK 인터페이스 제한사항을 참조하세요.
UnsupportedAppUsage
주석은 생성된 코드의 동작에 영향을 주지 않습니다. 이 주석은 생성된 자바 클래스에 대해 동일한 이름의 자바 주석으로만 주석을 지정합니다.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
이 주석은 자바가 아닌 백엔드에서는 작동하지 않습니다.
Backing
Backing
주석은 AIDL enum 유형의 저장소 유형을 지정합니다.
@Backing(type="int")
enum Color { RED, BLUE, }
CPP 백엔드에서 위 코드는 int32_t
유형의 C++ enum 클래스를 내보냅니다.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
주석이 생략되면 type
은 byte
인 것으로 간주되며, 이는 CPP 백엔드의 경우 int8_t
에 매핑됩니다.
type
인수는 다음 정수 유형으로만 설정할 수 있습니다.
byte
(8비트 와이드)int
(32비트 와이드)long
(64비트 와이드)
JavaOnlyStableParcelable
JavaOnlyStableParcelable
은 다른 안정적인 AIDL 유형에서 참조될 수 있도록 parcelable 선언(정의가 아님)을 안정적인 것으로 표시합니다.
안정적인 AIDL을 사용하려면 모든 사용자 정의 유형이 안정적이어야 합니다. parcelable의 경우 안정적이려면 해당 필드가 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
}
parcelable이 구조화되지 않았다면(또는 선언만 되었다면) 참조할 수 없습니다.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
을 사용하면 참조하는 parcelable이 Android SDK의 일부로 이미 안전하게 제공되는 경우에 검사를 재정의할 수 있습니다.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
는 자바 백엔드에서 parcelable 유형의 메서드를 자동으로 생성합니다.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
주석에는 생성할 항목을 제어하기 위한 추가 매개변수가 필요합니다. 지원되는 매개변수는 다음과 같습니다.
equals=true
는equals
및hashCode
메서드를 생성합니다.toString=true
는 유형 및 필드 이름을 출력하는toString
메서드를 생성합니다. 예:Data{number: 42, str: foo}
JavaDefault
Android 13에 추가된 JavaDefault
는 setDefaultImpl
의 기본 구현 버전 관리 지원이 생성되는지 여부를 제어합니다. 이 지원은 공간 절약을 위해 더 이상 기본적으로 생성되지 않습니다.
JavaPassthrough
JavaPassthrough
를 사용하면 생성된 자바 API에 임의의 자바 주석을 지정할 수 있습니다.
AIDL의 다음 주석은
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
생성된 자바 코드에서 다음과 같은
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
주석이 됩니다.
annotation
매개변수의 값을 직접 내보냅니다. AIDL 컴파일러는 매개변수의 값을 검토하지 않습니다. 자바 수준 구문 오류가 있다면 이 오류는 AIDL 컴파일러가 아니라 자바 컴파일러에 의해 포착됩니다.
이 주석은 어떤 AIDL 항목에든 연결될 수 있습니다. 이 주석은 자바가 아닌 백엔드에서는 작동하지 않습니다.
FixedSize
FixedSize
는 구조화된 parcelable을 고정 크기로 표시합니다. parcelable이 고정 크기로 표시되면 parcelable에 새 필드를 추가할 수 없습니다. 또한 기본 유형, 고정 크기 배열, enum 및 FixedSize
로 표시된 기타 parcelable을 포함하여 parcelable의 모든 필드는 고정 크기 유형이어야 합니다.
이 주석은 서로 다른 비트에 대해 어떠한 보장도 제공하지 않으며 혼합 비트 통신에 사용되어서는 안 됩니다.
Descriptor
Descriptor
는 인터페이스의 인터페이스 설명어를 강제로 지정합니다.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
위 인터페이스의 설명어는 android.bar.IWorld
입니다. Descriptor
주석이 누락되었다면 설명어는 android.foo.IHello
입니다.
이 주석은 이미 게시된 인터페이스의 이름을 바꿀 때 유용합니다. 이름이 변경되는 인터페이스의 설명어를 이름 변경 전의 인터페이스 설명어와 동일하게 만들면 두 인터페이스가 서로 통신할 수 있습니다.
주석의 @hide
AIDL 컴파일러는 주석에서 @hide
를 인식하여 Metalava가 이를 인식할 수 있도록 자바 출력으로 전달합니다. 이 주석은 AIDL API가 SDK API가 아니라는 것을 Android 빌드 시스템이 알 수 있도록 지원합니다.
주석의 @deprecated
AIDL 컴파일러는 주석에서 @deprecated
를 더 이상 사용해서는 안 되는 AIDL 항목을 식별하는 태그로 인식합니다.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
각 백엔드는 클라이언트 코드가 지원 중단된 항목을 참조할 때 경고가 발생할 수 있도록 백엔드별 주석/속성을 사용하여 지원 중단된 항목을 표시합니다.
예를 들어, 자바 생성 코드에는 @Deprecated
주석과 @deprecated
태그가 연결됩니다.