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)
के अमान्य इस्तेमाल पर चेतावनियां मिलती हैं. ऐसा तब होता है, जब मैथड में सही अनुमतियों के बिना कोई इंटेंट पास किया जाता है. इसकी जानकारी, पहली इमेज में दी गई है.
बिल्ड टूल, 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)
का इस्तेमाल करके, दूसरे डेवलपर को अपने टेस्टिंग एपीआई ऐक्सेस करने से रोकें.
एनोटेट किए गए एपीआई को सिर्फ़ टेस्टिंग कोड ऐक्सेस कर सकता है. इससे, दूसरे डेवलपर को सिर्फ़ टेस्टिंग के मकसद से बनाए गए एपीआई का इस्तेमाल करने से रोका जा सकता है.