Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

AIDL의 주석

AIDL은 주석이 지정된 요소에 관한 추가 정보를 AIDL 컴파일러에 제공하는 주석을 지원하며 이는 생성된 스터브 코드에도 영향을 줍니다.

구문은 다음과 같이 자바 구문과 유사합니다.

    @AnnotationName(argument1=value, argument2=value) AidlEntity

여기서 AnnotationName은 주석의 이름이며 AidlEntityinterface 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
JavaPassthrough S
FixedSize S
Descriptor S

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 S 이상에서는 std::optional<T>에 매핑됩니다.

NDK 백엔드에서 @nullable T는 항상 std::optional<T>에 매핑됩니다.

T[] 또는 List<T>와 같이 목록과 유사한 유형 L의 경우 @nullable Lstd::optional<std::vector<std::optional<T>>>(또는 Android 11 이하용 CPP 백엔드의 경우 std::unique_ptr<std::vector<std::unique_ptr<T>>>)에 매핑됩니다.

이 매핑에는 예외가 있습니다. TIBinder 또는 AIDL 인터페이스일 때 @nullable은 작동하지 않습니다. 즉, @nullable IBinderIBinder는 모두 android::sp<IBinder>(강력한 포인터이기 때문에 이미 nullable임)에 동일하게 매핑됩니다.

utf8InCpp

utf8InCppString이 CPP 백엔드에 관해 UTF8 형식으로 표시된다는 것을 선언합니다. 이름에서 알 수 있듯이 이 주석은 다른 백엔드에서는 작동하지 않습니다. 특히 String은 자바 백엔드에서 항상 UTF16이며 NDK 백엔드에서는 UTF8입니다.

반환 값, 매개변수, 상수 선언, parcelable 필드 등 String 유형을 사용할 수 있는 곳이면 어디에나 이 주석을 지정할 수 있습니다.

CPP 백엔드의 경우 AIDL의 @utf8InCpp Stringstd::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로 주석이 지정될 때 유형에서 참조되는 다른 유형도 이와 같이 주석이 지정되어야 합니다. 아래 예에서 DataIBar는 모두 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 {...}

이 주석은 자바가 아닌 백엔드에서는 작동하지 않습니다.

Hide

Hide 주석은 UnsupportedAppUsage와 유사합니다. 그리고 API가 Android API의 일부가 아님을 나타내는 자바 주석 android.annotation.Hide에 직접 매핑됩니다.

android.annotation.Hide 주석은 API를 숨기는 또 다른 방법으로, 이 작업은 일반적으로 API에 관한 의견 어딘가에 @hide 문자열 리터럴을 추가하여 완료됩니다.

이 주석은 자바가 아닌 백엔드에서는 작동하지 않습니다.

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,
}

주석이 생략되면 typebyte인 것으로 간주되며, 이는 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 parceable

parcelable AnotherData {
    Data d; // Error
}

JavaOnlyStableParcelable을 사용하면 참조하는 parcelable이 Android SDK의 일부로 이미 안전하게 제공되는 경우에 검사를 재정의할 수 있습니다.

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // Ok
}

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입니다.

이 주석은 이미 게시된 인터페이스의 이름을 바꿀 때 유용합니다. 이름이 변경되는 인터페이스의 설명어를 이름 변경 전의 인터페이스 설명어와 동일하게 만들면 두 인터페이스가 서로 통신할 수 있습니다.