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

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")
}

Groovy

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 के null एनोटेशन का इस्तेमाल करता हो, ताकि कोड की जांच के दौरान, लिंट चेकर आपको सही तरीके से सूचना दे सके.

संसाधन के एनोटेशन

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

ऐसे कोड में, पैरामीटर के लिए किसी खास तरह के संसाधन, जैसे कि 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) method, इंटेंट पर दी गई अप्रत्यक्ष अनुमति का इस्तेमाल करता है:

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) का इस्तेमाल करके, दूसरे डेवलपर को अपने टेस्टिंग एपीआई ऐक्सेस करने से रोकें.

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