एआईडीएल में एनोटेशन

एआईडीएल, ऐसे एनोटेशन के साथ काम करता है जो एआईडीएल कंपाइलर को ज़्यादा जानकारी देते हैं इससे जनरेट किए गए स्टब कोड पर भी असर पड़ता है.

सिंटैक्स, Java के समान है:

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

यहां, AnnotationName एनोटेशन का नाम है और AidlEntity इसका मतलब है interface Foo, void method() या int arg जैसी कोई AIDL इकाई. अगर आप एनोटेशन उसे फ़ॉलो करने वाली इकाई से जुड़ा होता है.

कुछ एनोटेशन में, ब्रैकेट के अंदर आर्ग्युमेंट सेट किए जा सकते हैं. जैसा कि ऊपर दिखाया गया है. जिन एनोटेशन में कोई तर्क नहीं होता उन्हें ब्रैकेट की ज़रूरत नहीं होती है. उदाहरण के लिए:

@AnnotationName AidlEntity

ये एनोटेशन Java के समान नहीं हैं एनोटेशन हालांकि वे बहुत मिलते-जुलते दिखते हैं. उपयोगकर्ता, कस्टम एआईडीएल तय नहीं कर सकते एनोटेशन; व्याख्याएं पूरी तरह से पहले से तय होती हैं. कुछ एनोटेशन केवल हैं और ये अन्य बैकएंड में काम नहीं करते. उनके पास अलग-अलग सीमित नहीं किए जा सकते.

पहले से तय किए गए एआईडीएल एनोटेशन की सूची यहां दी गई है:

एनोटेशन 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

अमान्य

nullable बताता है कि हो सकता है कि एनोटेट की गई इकाई की वैल्यू न दी गई हो.

इस जानकारी को सिर्फ़ तरीके के रिटर्न टाइप, तरीके पैरामीटर, और पार्स किए जा सकने वाले फ़ील्ड.

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

यह जानकारी Java बैकएंड के लिए काम नहीं करती. ऐसा इसलिए होता है, क्योंकि Java में सभी नॉन-प्रीमिटिव टाइप को रेफ़रंस के तौर पर पास किया जाता है, जो null हो सकते हैं.

सीपीपी बैकएंड में, Android में @nullable T, std::unique_ptr<T> को मैप करता है 11 या उससे कम और Android में std::optional<T> तक 12 या उससे ज़्यादा.

एनडीके बैकएंड में, @nullable T हमेशा std::optional<T> को मैप करता है.

सूची-जैसे प्रकार के लिए L जैसे T[] या List<T>, @nullable L के लिए मैप std::optional<std::vector<std::optional<T>>> (या सीपीपी बैकएंड के मामले में std::unique_ptr<std::vector<std::unique_ptr<T>>> Android 11 या इससे पहले के वर्शन के लिए.

इस मैपिंग के लिए एक अपवाद है. जब T IBinder या एआईडीएल इंटरफ़ेस है, @nullable नो-ऑप है. दूसरे शब्दों में, दोनों @nullable IBinder और IBinder, android::sp<IBinder> पर समान रूप से मैप करते हैं, जो कि पहले से ही शून्य है, क्योंकि यह एक असरदार पॉइंटर है (सीपीपी पर लिखा है अब भी दिख रहा है) शून्यता लागू करने के बाद भी, टाइप android::sp<IBinder> है).

Android 13 और इसके बाद के वर्शन में, @nullable(heap=true) का इस्तेमाल इन कामों के लिए किया जा सकता है पार्स किए जा सकने वाले फ़ील्ड से मिले डेटा को मॉडल रिकर्सिव टाइप में बदल सकते हैं. @nullable(heap=true) का इस्तेमाल नहीं किया जा सकता तरीका पैरामीटर और रिटर्न टाइप के हिसाब से तय होता है. जब इसके साथ एनोटेट किया जाता है, तो फ़ील्ड सीपीपी/एनडीके में हीप-असाइन किए गए रेफ़रंस std::unique_ptr<T> के साथ मैप किया गया हो बैकएंड. Java बैकएंड में, @nullable(heap=true) काम नहीं करता है.

utf8InCpp

utf8InCpp एलान करता है कि सीपीपी के लिए, String को UTF8 फ़ॉर्मैट में दिखाया जाता है बैकएंड. जैसा कि इसके नाम से पता चलता है कि यह एनोटेशन दूसरे बैकएंड के लिए काम नहीं करता. खास तौर पर, Java बैकएंड में String हमेशा UTF16 और NDK में UTF8 होता है बैकएंड.

इस एनोटेशन को कहीं भी अटैच किया जा सकता है, जहां String टाइप का इस्तेमाल किया जा सकता है, इसमें रिटर्न वैल्यू, पैरामीटर, कॉन्सटैंट जानकारी, और पार्सल करने लायक जानकारी शामिल है फ़ील्ड.

सीपीपी बैकएंड के लिए, एआईडीएल मैप में std::string के लिए @utf8InCpp String, जबकि String बिना एनोटेशन के android::String16 पर मैप होता है, जहां UTF16 का इस्तेमाल किया जाता है.

ध्यान दें कि utf8InCpp एनोटेशन के मौजूद होने पर, तार पर स्ट्रिंग ट्रांसमिट की जाती हैं. स्ट्रिंग हमेशा UTF16 के तौर पर ट्रांसमिट की जाती हैं डाला गया है. utf8InCpp से जुड़ी व्याख्या वाली स्ट्रिंग को इससे पहले UTF16 में बदल दिया जाता है भेजा गया. जब कोई स्ट्रिंग मिलती है, तो उसे UTF16 से UTF8 में बदल दिया जाता है, अगर वह को utf8InCpp के तौर पर एनोटेट किया गया था.

विंटएफ़स्टेबिलिटी

VintfStability बताता है कि उपयोगकर्ता ने जो टाइप (इंटरफ़ेस, पार्स किया जा सकने वाला, और enum) का इस्तेमाल सिस्टम और वेंडर डोमेन में किया जा सकता है. यहां जाएं: एचएएल के लिए एआईडीएल: सिस्टम-वेंडर इंटरऑपरेबिलिटी.

एनोटेशन से टाइप के हस्ताक्षर में बदलाव नहीं होता. हालांकि, इसे सेट करने पर, टाइप के इंस्टेंस को स्टेबल के तौर पर मार्क किया गया है, ताकि यह हर जगह यात्रा कर सके वेंडर और सिस्टम प्रोसेस.

एनोटेशन को सिर्फ़ उपयोगकर्ता की ओर से तय किए गए टाइप की जानकारी के साथ अटैच किया जा सकता है, जैसा कि दिखाया गया है यहां:

@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_interface सूंग मॉड्यूल टाइप का इस्तेमाल करके बनाया जा सकता है. stability प्रॉपर्टी को "vintf" पर सेट किया गया है.

aidl_interface {
    name: "my_interface",
    srcs: [...],
    stability: "vintf",
}

इस्तेमाल नहीं किया जा सकने वाला ऐप्लिकेशन

UnsupportedAppUsage एनोटेशन से पता चलता है कि एनोटेशन किया गया एआईडीएल टाइप बिना SDK टूल वाले इंटरफ़ेस का हिस्सा है जिसे लेगसी ऐप्लिकेशन से ऐक्सेस किया जा सकता है. SDK टूल के अलावा अन्य सेवाओं पर लगने वाली पाबंदियां देखें इंटरफ़ेस को पढ़ें.

UnsupportedAppUsage एनोटेशन से, जनरेट किया गया कोड. यह व्याख्या सिर्फ़ जनरेट की गई Java क्लास के साथ एनोटेट करती है इसी नाम की Java व्याख्या.

// in AIDL
@UnsupportedAppUsage
interface IFoo {...}

// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}

यह गैर-Java बैकएंड के लिए काम नहीं करता.

बैकिंग

Backing एनोटेशन से यह पता चलता है कि एआईडीएल एनम टाइप का स्टोरेज टाइप क्या है.

@Backing(type="int")
enum Color { RED, BLUE, }

CPP बैकएंड में, इससे int32_t टाइप की C++ enum क्लास निकलती है.

enum class Color : int32_t {
    RED = 0,
    BLUE = 1,
}

अगर एनोटेशन को मिटा दिया जाता है, तो type को byte माना जाता है. यह सीपीपी बैकएंड के लिए, int8_t पर.

type आर्ग्युमेंट को सिर्फ़ इन इंटिग्रल टाइप पर सेट किया जा सकता है:

  • byte (8-बिट चौड़ा)
  • int (32-बिट चौड़ा)
  • long (64-बिट चौड़ा)

NdkOnlyStableParcelable

NdkOnlyStableParcelable, पार्स किया जा सकने वाला एलान मार्क करता है (परिभाषा नहीं है) ताकि इसे अन्य स्थिर एआईडीएल टाइप से रेफ़रंस लिया जा सके. यह JavaOnlyStableParcelable के जैसा है, लेकिन NdkOnlyStableParcelable, एनडीके के लिए पार्सल किए जा सकने वाले एलान को स्टेबल के तौर पर मार्क करता है Java के बजाय, बैकएंड पर काम करता है.

पार्स किए जा सकने वाले इस टूल का इस्तेमाल करने के लिए:

  • आपको ndk_header तय करना होगा.
  • आपके पास ऐसी NDK लाइब्रेरी होनी चाहिए जिसमें पार्सल किया जा सके. साथ ही, लाइब्रेरी में को लाइब्रेरी में कंपाइल किया जाएगा. उदाहरण के लिए, कोर बिल्ड सिस्टम में cc_* मॉड्यूल में, static_libs या shared_libs का इस्तेमाल किया जा सकता है. aidl_interface के लिए, यह जोड़ें Android.bp में additional_shared_libraries से कम की लाइब्रेरी.

JavaOnlyStableParcelable

JavaOnlyStableParcelable, पार्स किया जा सकने वाला एलान मार्क करता है (परिभाषा नहीं है) ताकि इसे अन्य स्थिर एआईडीएल टाइप से रेफ़रंस लिया जा सके.

स्थिर एआईडीएल का इस्तेमाल करने के लिए ज़रूरी है कि उपयोगकर्ता के तय किए गए सभी टाइप स्टेबल हों. इसके लिए पार्सल होने के लायक हैं, तो स्थायी होने के लिए यह ज़रूरी है कि इसके फ़ील्ड 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 Data; // Data is NOT a structured parcelable

parcelable AnotherData {
    Data d; // Error
}

पार्सल होने पर, JavaOnlyStableParcelable आपको चेक को बदलने की सुविधा देता है का इस्तेमाल, पहले से ही Android SDK के हिस्से के तौर पर सुरक्षित तरीके से किया जा सकता है.

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // OK
}

JavaDerive

JavaDerive, पार्सल किए जा सकने वाले टाइप के लिए अपने-आप तरीके जनरेट करता है: Java बैकएंड.

@JavaDerive(equals = true, toString = true)
parcelable Data {
  int number;
  String str;
}

क्या कार्रवाई करनी है, यह कंट्रोल करने के लिए, एनोटेशन में अतिरिक्त पैरामीटर की ज़रूरत होती है जनरेट करना. इस्तेमाल किए जा सकने वाले पैरामीटर ये हैं:

  • equals=true, equals और hashCode तरीके जनरेट करता है.
  • toString=true, toString तरीका जनरेट करता है. यह तरीका, टाइप का नाम प्रिंट करता है और फ़ील्ड शामिल करें. उदाहरण के लिए: Data{number: 42, str: foo}

Javaडिफ़ॉल्ट

Android 13 में जोड़े गए JavaDefault का इस्तेमाल करके, यह कंट्रोल किया जा सकता है कि डिफ़ॉल्ट रूप से, वर्शन बनाने की सुविधा जनरेट की जाती है (इसके लिए setDefaultImpl). यह सहायता अब डिफ़ॉल्ट रूप से जनरेट नहीं होती, ताकि जगह बचाएं.

Javaपासथ्रू

JavaPassthrough की मदद से, जनरेट किए गए Java API को किसी आर्बिट्ररी तरीके से एनोटेट किया जा सकता है Java के बारे में जानकारी.

एआईडीएल में ये एनोटेशन

@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 पैरामीटर की वैल्यू सीधे तौर पर जनरेट होती है. एआईडीएल कंपाइलर पैरामीटर की वैल्यू नहीं देखता. अगर आपको Java-लेवल सिंटैक्स में गड़बड़ी है. इसे AIDL कंपाइलर के ज़रिए नहीं रोका जाएगा, बल्कि Java कंपाइलर.

यह जानकारी किसी भी एआईडीएल इकाई के साथ अटैच की जा सकती है. इस एनोटेशन में कोई बदलाव नहीं किया गया है का इस्तेमाल नहीं कर सकता.

तय साइज़

FixedSize स्ट्रक्चर्ड पार्सल को तय साइज़ के तौर पर मार्क करता है. चिह्नित होने के बाद, पार्सल करने लायक फ़ील्ड में नए फ़ील्ड नहीं जोड़े जा सकेंगे. के सभी फ़ील्ड पार्स किए जा सकने वाले कोड का साइज़ भी तय होना चाहिए. इनमें प्रिमिटिव टाइप शामिल हैं, enum, तय साइज़ के अरे, और FixedSize के निशान वाले दूसरे पार्स किए जा सकने वाले एलिमेंट.

यह अलग-अलग कटने के लिए कोई गारंटी नहीं देता है और इसे नहीं माना जाना चाहिए मिक्स-बिटनेस कम्यूनिकेशन के लिए निर्भर थे.

जानकारी

Descriptor ज़बरदस्ती किसी इंटरफ़ेस का इंटरफ़ेस डिस्क्रिप्टर तय करता है.

package android.foo;

@Descriptor(value="android.bar.IWorld")
interface IHello {...}

इस इंटरफ़ेस का डिस्क्रिप्टर android.bar.IWorld है. अगर Descriptor एनोटेशन मौजूद नहीं है, डिस्क्रिप्टर यह होगा android.foo.IHello.

यह पहले से पब्लिश किए गए इंटरफ़ेस का नाम बदलने के लिए सही है. आसानी से बदले गए नाम वाले इंटरफ़ेस का डिस्क्रिप्टर, इंटरफ़ेस के डिस्क्रिप्टर जैसा ही होता है नाम बदलने से पहले, दोनों इंटरफ़ेस एक-दूसरे से बात कर पाते हैं.

@टिप्पणियों में छिपाएं

एआईडीएल कंपाइलर टिप्पणियों में @hide की पहचान करता है और उसे पास करता है ले सकते हैं. इस टिप्पणी से पक्का होता है कि Android बिल्ड सिस्टम से पता चलता है कि एआईडीएल एपीआई, SDK टूल के एपीआई नहीं हैं.

टिप्पणियों में @अब काम नहीं करेगा

एआईडीएल कंपाइलर टिप्पणियों में @deprecated की पहचान एक टैग के रूप में करता है, ताकि एआईडीएल इकाई, जिसका अब इस्तेमाल नहीं किया जाना चाहिए.

interface IFoo {
  /** @deprecated use bar() instead */
  void foo();
  void bar();
}

किसी बैकएंड से जुड़ी खास जानकारी के साथ हर बैकएंड, काम न करने वाली इकाइयों को मार्क करता है या एट्रिब्यूट का इस्तेमाल करें, ताकि क्लाइंट कोड के काम न करने वाले का ज़िक्र करने पर उसे चेतावनी दी जाए इकाइयां. उदाहरण के लिए, @Deprecated एनोटेशन और @deprecated टैग Java से जनरेट किए गए कोड से जुड़े हुए हैं.