एनोटेशन की मदद से कोड की जांच को बेहतर बनाना

lint जैसे कोड की जांच करने वाले टूल का इस्तेमाल करके, आपको समस्याओं का पता लगाने और अपने कोड को बेहतर बनाने में मदद मिल सकती है. हालांकि, जांच करने वाले टूल सिर्फ़ इतना ही अनुमान लगा सकते हैं. उदाहरण के लिए, Android रिसॉर्स आईडी, स्ट्रिंग, ग्राफ़िक, रंग, और दूसरे रिसॉर्स टाइप की पहचान करने के लिए int का इस्तेमाल करते हैं. इसलिए, जांच करने वाले टूल यह नहीं बता सकते कि आपने स्ट्रिंग रिसॉर्स को तब कहां बताया है, जब आपको रंग रिसॉर्स का इस्तेमाल करना चाहिए था. इस स्थिति का मतलब है कि आपका ऐप्लिकेशन गलत तरीके से रेंडर हो सकता है या बिलकुल भी नहीं चल सकता. भले ही, आपने कोड की जांच करने की सुविधा का इस्तेमाल किया हो.

एनोटेशन की मदद से, कोड की जांच करने वाले टूल को अहम जानकारी दी जा सकती है. जैसे, कोड में मौजूद ऐसी समस्याओं का पता लगाने में मदद करने के लिए, लिंट टूल को अहम जानकारी दी जा सकती है जो आसानी से नहीं दिखती हैं. एनोटेशन, मेटाडेटा टैग के तौर पर जोड़े जाते हैं. इन्हें वैरिएबल, पैरामीटर, और रिटर्न वैल्यू से अटैच किया जाता है, ताकि मेथड की रिटर्न वैल्यू, पास किए गए पैरामीटर, स्थानीय वैरिएबल, और फ़ील्ड की जांच की जा सके. कोड की जांच करने वाले टूल के साथ इस्तेमाल करने पर, एनोटेशन की मदद से, आपको कई समस्याओं का पता चल सकता है. जैसे, नल पॉइंटर अपवाद और संसाधन टाइप के संघर्ष.

Android, Jetpack ऐनोटेशन लाइब्रेरी की मदद से कई तरह के ऐनोटेशन इस्तेमाल करता है. लाइब्रेरी को androidx.annotation पैकेज के ज़रिए ऐक्सेस किया जा सकता है.

ध्यान दें: अगर किसी मॉड्यूल में एनोटेशन प्रोसेसर पर डिपेंडेंसी है, तो उस डिपेंडेंसी को जोड़ने के लिए, आपको Kotlin के लिए kapt या ksp डिपेंडेंसी कॉन्फ़िगरेशन या Java के लिए annotationProcessor डिपेंडेंसी कॉन्फ़िगरेशन का इस्तेमाल करना होगा.

अपने प्रोजेक्ट में एनोटेशन जोड़ना

अपने प्रोजेक्ट में एनोटेशन चालू करने के लिए, अपनी लाइब्रेरी या ऐप्लिकेशन में androidx.annotation:annotation डिपेंडेंसी जोड़ें. कोड की जांच या lint टास्क चलाने पर, जोड़े गए किसी भी एनोटेशन की जांच की जाती है.

Jetpack Annotations लाइब्रेरी की डिपेंडेंसी जोड़ना

Jetpack Annotations लाइब्रेरी को Google की मेवन रिपॉज़िटरी पर पब्लिश किया गया है. अपने प्रोजेक्ट में Jetpack Anotations लाइब्रेरी जोड़ने के लिए, अपनी build.gradle या build.gradle.kts फ़ाइल के dependencies ब्लॉक में यह लाइन शामिल करें:

Kotlin

dependencies {
    implementation("androidx.annotation:annotation:1.9.1")
}

ग्रूवी

dependencies {
    implementation 'androidx.annotation:annotation:1.9.1'
}
इसके बाद, टूलबार या सिंक करने की सूचना में, अभी सिंक करें पर क्लिक करें.

अगर अपने लाइब्रेरी मॉड्यूल में एनोटेशन का इस्तेमाल किया जाता है, तो एनोटेशन को annotations.zip फ़ाइल में, एक्सएमएल फ़ॉर्मैट में Android Archive (AAR) आर्टफ़ैक्ट के हिस्से के तौर पर शामिल किया जाता है. androidx.annotation डिपेंडेंसी जोड़ने से, आपकी लाइब्रेरी के डाउनस्ट्रीम उपयोगकर्ताओं के लिए कोई डिपेंडेंसी नहीं बनती.

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

Jetpack के डेटा स्टोर में शामिल एनोटेशन की पूरी सूची देखने के लिए, Jetpack एनोटेशन लाइब्रेरी का रेफ़रंस देखें या import androidx.annotation. स्टेटमेंट के लिए उपलब्ध विकल्पों को दिखाने के लिए, ऑटोकंप्लीट की सुविधा का इस्तेमाल करें.

कोड की जांच करें

Android Studio से कोड की जांच शुरू करने के लिए, मेन्यू से विश्लेषण करें > कोड की जांच करें चुनें. इस जांच में एनोटेशन की पुष्टि करना और लिंट के अपने-आप जांच होने की सुविधा शामिल है. Android Studio, संभावित समस्याओं को फ़्लैग करने के लिए, विरोध के मैसेज दिखाता है. ये समस्याएं तब होती हैं, जब आपका कोड एनोटेशन से मेल नहीं खाता. साथ ही, Android Studio संभावित समाधानों के सुझाव भी देता है.

आप कमांड लाइन का इस्तेमाल करके lint टास्क चलाकर भी एनोटेशन लागू कर सकते हैं. इससे, लगातार इंटीग्रेट करने वाले सर्वर की समस्याओं को फ़्लैग करने में मदद मिल सकती है. हालांकि, lint टास्क में शून्य वाले एनोटेशन लागू नहीं होते हैं. इनके बारे में इस सेक्शन में बताया गया है. ऐसा सिर्फ़ Android Studio पर होता है. लिंट जांच को चालू करने और चलाने के बारे में ज़्यादा जानकारी के लिए, लिंट जांच की मदद से अपने कोड को बेहतर बनाना देखें.

हालांकि, एनोटेशन के मेल न खाने से चेतावनियां जनरेट होती हैं, लेकिन ये चेतावनियां आपके ऐप्लिकेशन को कंपाइल करने से नहीं रोकतीं.

शून्य होने की जानकारी देने वाले एनोटेशन

वैल्यू शून्य हो सकती है या नहीं, यह लागू करने के लिए Java कोड में, बिना वैल्यू वाले एनोटेशन काम आ सकते हैं. ये Kotlin कोड में कम काम के होते हैं, क्योंकि Kotlin में वैल्यू न होने की स्थिति के लिए पहले से नियम मौजूद होते हैं. ये नियम, कोड को संकलित करने के समय लागू होते हैं.

किसी दिए गए वैरिएबल, पैरामीटर या रिटर्न वैल्यू के शून्य होने की जांच करने के लिए, @Nullable और @NonNull एनोटेशन जोड़ें. @Nullable एनोटेशन से ऐसे वैरिएबल, पैरामीटर या रिटर्न वैल्यू के बारे में पता चलता है जो शून्य हो सकता है. @NonNull से किसी ऐसे वैरिएबल, पैरामीटर या रिटर्न वैल्यू का पता चलता है जो शून्य नहीं हो सकती.

उदाहरण के लिए, अगर किसी ऐसे लोकल वैरिएबल को पैरामीटर के तौर पर किसी ऐसे तरीके में पास किया जाता है जिसमें कोई वैल्यू नहीं है और उस पैरामीटर में @NonNull एनोटेशन जुड़ा है, तो कोड बनाने पर एक चेतावनी जनरेट होती है. इससे पता चलता है कि कोई वैल्यू मौजूद है. साथ ही, @Nullable से मार्क किए गए किसी तरीके के नतीजे का रेफ़रंस देने से पहले, यह जांच किए बिना कि नतीजा शून्य है या नहीं, शून्यता की चेतावनी जनरेट होती है. किसी तरीके की रिटर्न वैल्यू पर @Nullable का इस्तेमाल सिर्फ़ तब करें, जब तरीके के हर इस्तेमाल के लिए साफ़ तौर पर शून्य की जांच की जानी हो.

यहां दिए गए उदाहरण में, वैल्यू न होने की स्थिति के बारे में बताया गया है. Kotlin के उदाहरण के तौर पर दिए गए कोड में, @NonNull एनोटेशन का इस्तेमाल नहीं किया गया है. ऐसा इसलिए है, क्योंकि नॉन-नल्यबल टाइप तय करने पर, यह जनरेट किए गए बाइटकोड में अपने-आप जुड़ जाता है. Java का उदाहरण, context और attrs पैरामीटर में मौजूद @NonNull एनोटेशन का इस्तेमाल करके, यह पता लगाता है कि पास की गई पैरामीटर वैल्यू शून्य नहीं हैं. यह यह भी जांचता है कि onCreateView() तरीका, null वैल्यू न दिखाता हो:

Kotlin

...
    /** Annotation not used because of the safe-call operator(?)**/
    override fun onCreateView(
            name: String?,
            context: Context,
            attrs: AttributeSet
    ): View? {
        ...
    }
...

Java

import androidx.annotation.NonNull;
...
    /** Add support for inflating the <fragment> tag. **/
    @NonNull
    @Override
    public View onCreateView(String name, @NonNull Context context,
      @NonNull AttributeSet attrs) {
      ...
      }
...

शून्य होने की जांच

Android Studio की मदद से, शून्य की क्षमता का विश्लेषण किया जा सकता है. इससे, अपने-आप कोड में शून्य होने की जानकारी का अनुमान लगाकर उसे शामिल किया जा सकता है. वैल्यू न होने की संभावना का विश्लेषण, आपके कोड में मौजूद सभी तरीकों की हैरारकी में कॉन्ट्रैक्ट को स्कैन करता है, ताकि यह पता लगाया जा सके:

  • ऐसे तरीकों को कॉल करना जो शून्य दिखा सकते हैं.
  • ऐसे तरीके जो शून्य नहीं दिखाते.
  • फ़ील्ड, लोकल वैरिएबल, और पैरामीटर जैसे वैरिएबल, जो शून्य हो सकते हैं.
  • फ़ील्ड, लोकल वैरिएबल, और पैरामीटर जैसे वैरिएबल, जिनमें शून्य वैल्यू नहीं हो सकती.

इसके बाद, विश्लेषण उन जगहों में अपने-आप शून्य एनोटेशन डाल देता है जिनका पता लगाया जाता है.

Android Studio में शून्य होने की स्थिति का विश्लेषण करने के लिए, विश्लेषण करें > शून्य वैल्यू डालें चुनें. Android Studio, आपके कोड में ढूंढी गई जगहों पर Android @Nullable और @NonNull एनोटेशन डालता है. शून्य विश्लेषण करने के बाद, इंजेक्ट किए गए एनोटेशन की पुष्टि करना अच्छा होता है.

ध्यान दें: शून्य वाले एनोटेशन जोड़ते समय, ऑटोकंप्लीट की सुविधा, Android शून्य एनोटेशन के बजाय IntelliJ @Nullable और @NotNull एनोटेशन का सुझाव दे सकती है. साथ ही, इससे जुड़ी लाइब्रेरी को अपने-आप इंपोर्ट किया जा सकता है. हालांकि, Android Studio के lint चेकर में सिर्फ़ Android के शून्य एनोटेशन दिखते हैं. एनोटेशन की पुष्टि करते समय, पक्का करें कि आपका प्रोजेक्ट, Android के शून्य एनोटेशन का इस्तेमाल करता हो, ताकि कोड की जांच के दौरान, लिंट चेकर आपको सही तरीके से सूचना दे सके.

संसाधन के बारे में जानकारी

रिसॉर्स टाइप की पुष्टि करना मददगार हो सकता है, क्योंकि Android में संसाधनों के रेफ़रंस, जैसे कि ड्रॉ करने लायक और स्ट्रिंग रिसॉर्स, पूर्णांक के तौर पर पास किए जाते हैं.

ऐसे कोड में, पैरामीटर के लिए किसी खास तरह के संसाधन, जैसे कि String का रेफ़रंस देने की उम्मीद की जाती है. इसे int के रेफ़रंस टाइप के तौर पर पास किया जा सकता है, लेकिन असल में यह किसी दूसरे तरह के संसाधन, जैसे कि R.string संसाधन का रेफ़रंस देता है.

उदाहरण के लिए, @StringRes एनोटेशन जोड़कर यह जांचें कि किसी रिसॉर्स पैरामीटर में R.string रेफ़रंस है या नहीं, जैसा कि यहां दिखाया गया है:

Kotlin

abstract fun setTitle(@StringRes resId: Int)

Java

public abstract void setTitle(@StringRes int resId)

कोड की जांच के दौरान, अगर पैरामीटर में R.string रेफ़रंस पास नहीं किया जाता है, तो एनोटेशन एक चेतावनी जनरेट करता है.

@DrawableRes, @DimenRes, @ColorRes, और @InterpolatorRes जैसे दूसरे रिसॉर्स टाइप के लिए, एनोटेशन को उसी एनोटेशन फ़ॉर्मैट का इस्तेमाल करके जोड़ा जा सकता है जिसे कोड की जांच के दौरान चलाया जा सकता है.

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

@ColorRes का इस्तेमाल करके यह बताया जा सकता है कि किसी पैरामीटर को कलर रिसॉर्स के तौर पर इस्तेमाल किया जाना चाहिए. हालांकि, RRGGBB या AARRGGBB फ़ॉर्मैट में मौजूद कलर इंटिजर को कलर रिसॉर्स के तौर पर नहीं माना जाता. इसके बजाय, @ColorInt एनोटेशन का इस्तेमाल करके यह बताएं कि पैरामीटर एक कलर इंटिजर होना चाहिए. बिल्ड टूल, एनोटेट किए गए तरीकों में रंग के पूर्णांक के बजाय, android.R.color.black जैसे कलर रिसॉर्स आईडी को पास करने वाले गलत कोड को फ़्लैग करेगा.

थ्रेड के बारे में जानकारी

थ्रेड के एनोटेशन से यह पता चलता है कि किसी खास तरह के थ्रेड से तरीके को कॉल किया गया है या नहीं. थ्रेड के लिए ये एनोटेशन इस्तेमाल किए जा सकते हैं:

बिल्ड टूल, @MainThread और @UiThread एनोटेशन को एक-दूसरे के साथ बदले जा सकने वाले एनोटेशन के तौर पर इस्तेमाल करते हैं. इसलिए, @MainThread वाले तरीकों से @UiThread वाले तरीकों को और @UiThread वाले तरीकों से @MainThread वाले तरीकों को कॉल किया जा सकता है. हालांकि, अलग-अलग थ्रेड पर कई व्यू वाले सिस्टम ऐप्लिकेशन के मामले में, यूज़र इंटरफ़ेस (यूआई) थ्रेड मुख्य थ्रेड से अलग हो सकती है. इसलिए, आपको ऐप्लिकेशन के व्यू हैरारकी से जुड़े तरीकों को @UiThread के साथ एनोटेट करना चाहिए. साथ ही, ऐप्लिकेशन के लाइफ़साइकल से जुड़े तरीकों को सिर्फ़ @MainThread के साथ एनोटेट करना चाहिए.

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

थ्रेड एनोटेशन का आम तौर पर इस्तेमाल, इस बात की पुष्टि करने के लिए किया जाता है कि @WorkerThread के साथ एनोटेट किए गए तरीकों या क्लास को सिर्फ़ सही बैकग्राउंड थ्रेड से कॉल किया जाता है.

वैल्यू की सीमा के ऐनोटेशन

इस्तेमाल किए गए पैरामीटर की वैल्यू की पुष्टि करने के लिए, @IntRange, @FloatRange, और @Size एनोटेशन का इस्तेमाल करें. @IntRange और @FloatRange दोनों सबसे ज़्यादा तब काम के होते हैं, जब इन्हें उन पैरामीटर पर लागू किया जाता है जिनमें उपयोगकर्ताओं को रेंज गलत लग सकती है.

@IntRange एनोटेशन की मदद से, यह पुष्टि की जाती है कि कोई पूर्णांक या लंबी पैरामीटर वैल्यू, तय की गई रेंज में है या नहीं. नीचे दिए गए उदाहरण से पता चलता है कि alpha पैरामीटर में 0 से 255 के बीच की कोई पूर्णांक वैल्यू होनी चाहिए:

Kotlin

fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }

Java

public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }

@FloatRange एनोटेशन यह जांच करता है कि फ़्लोट या डबल पैरामीटर की वैल्यू, फ़्लोटिंग पॉइंट वैल्यू की तय रेंज में है या नहीं. इस उदाहरण से पता चलता है कि alpha पैरामीटर में 0.0 से 1.0 के बीच की फ़्लोट वैल्यू होनी चाहिए:

Kotlin

fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}

Java

public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}

@Size एनोटेशन, किसी कलेक्शन या ऐरे के साइज़ या स्ट्रिंग की लंबाई की जांच करता है. @Size एनोटेशन का इस्तेमाल, इन क्वालिटी की पुष्टि करने के लिए किया जा सकता है:

  • कम से कम साइज़, जैसे कि @Size(min=2)
  • ज़्यादा से ज़्यादा साइज़, जैसे कि @Size(max=2)
  • साइज़ का सटीक डेटा, जैसे कि @Size(2)
  • ऐसी संख्या जिसका साइज़, @Size(multiple=2) के मल्टीपल में होना चाहिए

उदाहरण के लिए, @Size(min=1) यह जांच करता है कि कोई कलेक्शन खाली है या नहीं. साथ ही, @Size(3) यह पुष्टि करता है कि किसी ऐरे में तीन वैल्यू मौजूद हैं.

इस उदाहरण में बताया गया है कि location कलेक्शन में कम से कम एक एलिमेंट होना ज़रूरी है:

Kotlin

fun getLocation(button: View, @Size(min=1) location: IntArray) {
    button.getLocationOnScreen(location)
}

Java

void getLocation(View button, @Size(min=1) int[] location) {
    button.getLocationOnScreen(location);
}

अनुमति से जुड़े एनोटेशन

किसी तरीके को कॉल करने वाले की अनुमतियों की पुष्टि करने के लिए, @RequiresPermission एनोटेशन का इस्तेमाल करें. मान्य अनुमतियों की सूची में से किसी एक अनुमति की जांच करने के लिए, anyOf एट्रिब्यूट का इस्तेमाल करें. अनुमतियों के सेट की जांच करने के लिए, allOf एट्रिब्यूट का इस्तेमाल करें. यहां दिए गए उदाहरण में, setWallpaper() तरीके के लिए एनोटेशन दिया गया है. इससे पता चलता है कि इस तरीके को कॉल करने वाले के पास permission.SET_WALLPAPERS अनुमति होनी चाहिए:

Kotlin

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
@Throws(IOException::class)
abstract fun setWallpaper(bitmap: Bitmap)

Java

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;

नीचे दिए गए उदाहरण में, copyImageFile() तरीके को कॉल करने वाले के पास, कॉपी की गई इमेज में मौजूद, बाहरी स्टोरेज और जगह की जानकारी के मेटाडेटा, दोनों को पढ़ने का ऐक्सेस होना चाहिए:

Kotlin

@RequiresPermission(allOf = [
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION
])
fun copyImageFile(dest: String, source: String) {
    ...
}

Java

@RequiresPermission(allOf = {
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION})
public static final void copyImageFile(String dest, String source) {
    //...
}

इंटेंट की अनुमतियों के लिए, अनुमति की ज़रूरी शर्त को उस स्ट्रिंग फ़ील्ड पर डालें जो इंटेंट ऐक्शन के नाम को तय करता है:

Kotlin

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"

Java

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
public static final String ACTION_REQUEST_DISCOVERABLE =
            "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";

कॉन्टेंट उपलब्ध कराने वाली उन कंपनियों के लिए अनुमतियां जिनके पास कॉन्टेंट को पढ़ने और उसमें बदलाव करने के लिए अलग-अलग अनुमतियां होनी चाहिए, हर अनुमति की ज़रूरत को @RequiresPermission.Read या @RequiresPermission.Write एनोटेशन में लपेटें:

Kotlin

@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")

Java

@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");

सीधे तौर पर नहीं मिलने वाली अनुमतियां

जब कोई अनुमति, किसी तरीके के पैरामीटर में दी गई खास वैल्यू पर निर्भर करती है, तो खास अनुमतियों को सूची में शामिल किए बिना, पैरामीटर पर @RequiresPermission का इस्तेमाल करें. उदाहरण के लिए, startActivity(Intent) तरीका, तरीके को पास किए गए इंटेंट पर, सीधे तौर पर नहीं दी गई अनुमति का इस्तेमाल करता है:

Kotlin

abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)

Java

public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)

सीधे तौर पर न दी जाने वाली अनुमतियों का इस्तेमाल करने पर, बिल्ड टूल डेटा फ़्लो का विश्लेषण करते हैं. इससे यह पता चलता है कि तरीके में पास किए गए आर्ग्युमेंट में, कोई @RequiresPermission एनोटेशन है या नहीं. इसके बाद, वे पैरामीटर से मौजूदा एनोटेशन को, तरीके पर लागू कर देते हैं. startActivity(Intent) उदाहरण में, Intent क्लास में एनोटेशन होने पर, startActivity(Intent) के अमान्य इस्तेमाल पर चेतावनियां दिखती हैं. ऐसा तब होता है, जब मैथड में सही अनुमतियों के बिना कोई इंटेंट पास किया जाता है. इसकी जानकारी, पहली इमेज में दी गई है.

पहला डायग्राम. startActivity(Intent) तरीके में, सीधे तौर पर अनुमति न देने की वजह से जनरेट हुई चेतावनी.

बिल्ड टूल Intent क्लास में, इससे जुड़े इंटेंट कार्रवाई के नाम पर की गई व्याख्या से startActivity(Intent) पर चेतावनी जनरेट करते हैं:

Kotlin

@RequiresPermission(Manifest.permission.CALL_PHONE)
const val ACTION_CALL = "android.intent.action.CALL"

Java

@RequiresPermission(Manifest.permission.CALL_PHONE)
public static final String ACTION_CALL = "android.intent.action.CALL";

ज़रूरत पड़ने पर, किसी तरीके के पैरामीटर को एनोटेट करते समय, @RequiresPermission.Read या @RequiresPermission.Write के बजाय @RequiresPermission का इस्तेमाल किया जा सकता है. हालांकि, अप्रत्यक्ष अनुमतियों के लिए, @RequiresPermission का इस्तेमाल, पढ़ने या लिखने की अनुमतियों के एनोटेशन के साथ नहीं किया जाना चाहिए.

रिटर्न वैल्यू के एनोटेशन

@CheckResult एनोटेशन का इस्तेमाल करके, पुष्टि करें कि किसी तरीके के नतीजे या रिटर्न वैल्यू का असल में इस्तेमाल किया गया है. @CheckResult के साथ, हर ऐसे तरीके के लिए एनोटेशन जोड़ने के बजाय, एनोटेशन जोड़ें जिससे संभावित रूप से भ्रमित करने वाले तरीकों के नतीजों को साफ़ तौर पर समझा जा सके.

उदाहरण के लिए, नए Java डेवलपर अक्सर गलत तरीके से यह सोचते हैं कि <String>.trim(), ओरिजनल स्ट्रिंग से स्पेस हटा देता है. @CheckResult के साथ एनोटेट करने पर, <String>.trim() के इस्तेमाल को फ़्लैग किया जाता है. ऐसा तब किया जाता है, जब कॉलर, मेथड की रिटर्न वैल्यू का इस्तेमाल न करता हो.

यहां दिए गए उदाहरण में, checkPermissions() विधि के लिए एनोटेशन दिया गया है, ताकि यह जांचा जा सके कि विधि की रिटर्न वैल्यू का असल में रेफ़रंस दिया गया है या नहीं. यह डेवलपर को सुझाए जाने वाले enforcePermission() तरीके का नाम भी बताता है:

Kotlin

@CheckResult(suggest = "#enforcePermission(String,int,int,String)")
abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int

Java

@CheckResult(suggest="#enforcePermission(String,int,int,String)")
public abstract int checkPermission(@NonNull String permission, int pid, int uid);

CallSuper एनोटेशन

@CallSuper एनोटेशन का इस्तेमाल करके, पुष्टि करें कि ओवरराइड करने का कोई तरीका, सुपर इंप्लीमेंटेशन को कॉल करता है.

इस उदाहरण में, onCreate() तरीके के बारे में बताया गया है, ताकि यह पक्का किया जा सके कि ओवरराइड करने के किसी भी तरीके को लागू करने पर, super.onCreate() को कॉल किया जाएगा:

Kotlin

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
}

Java

@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}

टाइपडेफ़ एनोटेशन

टाइपडेफ़ एनोटेशन यह जांच करते हैं कि कोई पैरामीटर, रिटर्न वैल्यू या फ़ील्ड, कॉन्स्टेंट के किसी खास सेट का रेफ़रंस देता है या नहीं. इनकी मदद से, कोड पूरा करने की सुविधा भी चालू की जा सकती है, ताकि तय किए गए कॉन्सटेंट अपने-आप मिल सकें.

@IntDef और @StringDef के एनोटेशन का इस्तेमाल करके, पूर्णांक और स्ट्रिंग सेट के एनोटेशन बनाएं. इससे, कोड के दूसरे तरह के रेफ़रंस की पुष्टि की जा सकती है.

टाइपडेफ़ एनोटेशन, एनोटेशन के नए टाइप का एलान करने के लिए @interface का इस्तेमाल करते हैं. @IntDef और @StringDef एनोटेशन, @Retention के साथ मिलकर नए एनोटेशन को एनोटेट करते हैं. साथ ही, ये एनोटेशन, एनोटेशन के टाइप को तय करने के लिए ज़रूरी हैं. @Retention(RetentionPolicy.SOURCE) एनोटेशन, कंपाइलर को बताता है कि एनोटेशन के लिए दिए गए डेटा को .class फ़ाइल में स्टोर न करें.

इस उदाहरण में, एनोटेशन बनाने का तरीका बताया गया है. इससे यह पता चलता है कि तरीके के पैरामीटर के तौर पर पास की गई वैल्यू, तय किए गए कॉन्सटेंट में से किसी एक का रेफ़रंस देती है या नहीं:

Kotlin

import androidx.annotation.IntDef
//...
// Define the list of accepted constants and declare the NavigationMode annotation.
@Retention(AnnotationRetention.SOURCE)
@IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS)
annotation class NavigationMode

// Declare the constants.
const val NAVIGATION_MODE_STANDARD = 0
const val NAVIGATION_MODE_LIST = 1
const val NAVIGATION_MODE_TABS = 2

abstract class ActionBar {

    // Decorate the target methods with the annotation.
    // Attach the annotation.
    @get:NavigationMode
    @setparam:NavigationMode
    abstract var navigationMode: Int

}

Java

import androidx.annotation.IntDef;
//...
public abstract class ActionBar {
    //...
    // Define the list of accepted constants and declare the NavigationMode annotation.
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
    public @interface NavigationMode {}

    // Declare the constants.
    public static final int NAVIGATION_MODE_STANDARD = 0;
    public static final int NAVIGATION_MODE_LIST = 1;
    public static final int NAVIGATION_MODE_TABS = 2;

    // Decorate the target methods with the annotation.
    @NavigationMode
    public abstract int getNavigationMode();

    // Attach the annotation.
    public abstract void setNavigationMode(@NavigationMode int mode);
}

इस कोड को बनाने पर, अगर mode पैरामीटर, तय की गई किसी एक स्थिर वैल्यू (NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST या NAVIGATION_MODE_TABS) का रेफ़रंस नहीं देता है, तो चेतावनी जनरेट होती है.

@IntDef और @IntRange को जोड़ें, ताकि यह बताया जा सके कि पूर्णांक, कॉन्सटेंट का दिया हुआ सेट हो सकता है या रेंज में मौजूद कोई वैल्यू हो सकती है.

फ़्लैग के साथ कॉन्स्टेंट को जोड़ने की सुविधा चालू करना

अगर उपयोगकर्ता, अनुमति वाले कॉन्स्टेंट को किसी फ़्लैग (जैसे, |, &, ^ वगैरह) के साथ जोड़ सकते हैं, तो flag एट्रिब्यूट की मदद से एनोटेशन तय किया जा सकता है. इससे यह पता लगाया जा सकता है कि कोई पैरामीटर या रिटर्न वैल्यू, मान्य पैटर्न का रेफ़रंस देती है या नहीं.

यहां दिए गए उदाहरण में, मान्य DISPLAY_ कॉन्स्टेंट की सूची के साथ DisplayOptions एनोटेशन बनाया गया है:

Kotlin

import androidx.annotation.IntDef
...

@IntDef(flag = true, value = [
    DISPLAY_USE_LOGO,
    DISPLAY_SHOW_HOME,
    DISPLAY_HOME_AS_UP,
    DISPLAY_SHOW_TITLE,
    DISPLAY_SHOW_CUSTOM
])
@Retention(AnnotationRetention.SOURCE)
annotation class DisplayOptions
...

Java

import androidx.annotation.IntDef;
...

@IntDef(flag=true, value={
        DISPLAY_USE_LOGO,
        DISPLAY_SHOW_HOME,
        DISPLAY_HOME_AS_UP,
        DISPLAY_SHOW_TITLE,
        DISPLAY_SHOW_CUSTOM
})
@Retention(RetentionPolicy.SOURCE)
public @interface DisplayOptions {}

...

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

एनोटेशन को बनाए रखना

@Keep एनोटेशन से यह पक्का होता है कि बिल्ड के समय कोड को छोटा करने पर, एनोटेट की गई क्लास या तरीके को न हटाया जाए. आम तौर पर, यह एनोटेशन उन तरीकों और क्लास में जोड़ा जाता है जिन्हें रिफ़्लेक्शन की मदद से ऐक्सेस किया जाता है. इससे कंपाइलर, कोड को इस्तेमाल न किए गए के तौर पर नहीं लेता.

चेतावनी: @Keep का इस्तेमाल करके जिन क्लास और तरीकों की व्याख्या की जाती है वे आपके ऐप्लिकेशन के APK में हमेशा दिखते हैं, भले ही आपने अपने ऐप्लिकेशन के लॉजिक में कभी भी इन क्लास और तरीकों का रेफ़रंस न दिया हो.

अपने ऐप्लिकेशन का साइज़ छोटा रखने के लिए, इस बात पर विचार करें कि क्या आपके ऐप्लिकेशन में हर @Keep एनोटेशन को बनाए रखना ज़रूरी है. अगर एनोटेट की गई क्लास या तरीके को ऐक्सेस करने के लिए रिफ़्लेक्शन का इस्तेमाल किया जाता है, तो अपने ProGuard नियमों में -if शर्त का इस्तेमाल करें. साथ ही, उस क्लास के बारे में बताएं जो रिफ़्लेक्शन कॉल करता है.

अपने कोड को छोटा करने और यह तय करने के तरीके के बारे में ज़्यादा जानने के लिए कि कौनसा कोड नहीं हटाया जाना चाहिए, अपने ऐप्लिकेशन को छोटा करना, उलझाना, और ऑप्टिमाइज़ करना लेख पढ़ें.

कोड दिखने की सेटिंग के एनोटेशन

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

जांच के लिए कोड को दिखाना

@VisibleForTesting एनोटेशन से पता चलता है कि एनोटेट किया गया तरीका, आम तौर पर ज़रूरी से ज़्यादा दिखता है, ताकि उस तरीके की जांच की जा सके. इस जानकारी में एक वैकल्पिक otherwise आर्ग्युमेंट होता है. इसकी मदद से, यह बताया जा सकता है कि इस तरीके के दिखने की स्थिति क्या होगी. इससे जांच के लिए, इस तरीके को नहीं दिखाया जा सकेगा. Lint, otherwise आर्ग्युमेंट का इस्तेमाल करके, तय की गई विज़िबिलिटी लागू करता है.

नीचे दिए गए उदाहरण में, myMethod() आम तौर पर private होता है, लेकिन यह जांच के लिए package-private होता है. VisibleForTesting.PRIVATE के साथ, अगर इस तरीके को private ऐक्सेस की अनुमति वाले कॉन्टेक्स्ट के बाहर से कॉल किया जाता है, तो लिंट एक मैसेज दिखाता है. जैसे, किसी दूसरी कंपाइलेशन यूनिट से.

Kotlin

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun myMethod() {
    ...
}

Java

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void myMethod() { ... }

यह बताने के लिए कि कोई तरीका सिर्फ़ टेस्टिंग के लिए मौजूद है, @VisibleForTesting(otherwise = VisibleForTesting.NONE) का इस्तेमाल भी किया जा सकता है. यह फ़ॉर्म, @RestrictTo(TESTS) का इस्तेमाल करने जैसा ही है. वे दोनों एक ही लिंट जांच करते हैं.

एपीआई पर पाबंदी लगाना

@RestrictTo एनोटेशन से पता चलता है कि एनोटेशन वाले एपीआई (पैकेज, क्लास या तरीका) का ऐक्सेस इस तरह से है:

सब-क्लास

सिर्फ़ सब-क्लास के लिए एपीआई का ऐक्सेस प्रतिबंधित करने के लिए, जानकारी देने वाले फ़ॉर्म @RestrictTo(RestrictTo.Scope.SUBCLASSES) का इस्तेमाल करें.

सिर्फ़ एनोटेट की गई क्लास को एक्सटेंड करने वाली क्लास ही इस एपीआई को ऐक्सेस कर सकती हैं. Java protected मॉडिफ़ायर काफ़ी पाबंदी वाला नहीं है, क्योंकि यह एक ही पैकेज में मौजूद, एक-दूसरे से अलग क्लास से ऐक्सेस करने की अनुमति देता है. इसके अलावा, कुछ मामलों में आपको आने वाले समय में किसी public तरीके का इस्तेमाल करने के लिए, उसे छोड़ना पड़ता है. ऐसा इसलिए, क्योंकि पहले से मौजूद protected और ओवरराइड किए गए public तरीके को कभी भी नहीं बनाया जा सकता. हालांकि, आपको यह संकेत देना होता है कि क्लास का इस्तेमाल सिर्फ़ क्लास या सबक्लास में किया जा सकता है.

लाइब्रेरी

एनोटेशन फ़ॉर्म @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) का इस्तेमाल करके, एपीआई के ऐक्सेस को सिर्फ़ अपनी लाइब्रेरी तक सीमित करें.

एनोटेट किए गए एपीआई को सिर्फ़ आपकी लाइब्रेरी का कोड ऐक्सेस कर सकता है. इससे, अपने कोड को अपनी पसंद के पैकेज के हिसाब से व्यवस्थित करने के साथ-साथ, उस कोड को मिलती-जुलती लाइब्रेरी के ग्रुप के साथ शेयर भी किया जा सकता है. यह विकल्प, उन Jetpack लाइब्रेरी के लिए पहले से ही उपलब्ध है जिनमें लागू करने के लिए बहुत सारा कोड है. यह कोड, बाहरी इस्तेमाल के लिए नहीं है. हालांकि, इसे अलग-अलग तरह की अन्य Jetpack लाइब्रेरी के साथ शेयर करने के लिए, इसे public होना चाहिए.

टेस्ट करना

एनोटेशन फ़ॉर्म @RestrictTo(RestrictTo.Scope.TESTS) का इस्तेमाल करके, दूसरे डेवलपर को अपने टेस्टिंग एपीआई ऐक्सेस करने से रोकें.

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