इस विषय में, Kotlin लैंग्वेज के कुछ सबसे काम के पहलुओं पर फ़ोकस किया गया है जब उसे Android के लिए डेवलप किया जा रहा हो.
फ़्रैगमेंट के साथ काम करना
Kotlin के कुछ सेक्शन को हाइलाइट करने के लिए, नीचे दिए गए सेक्शन में Fragment
के उदाहरण का इस्तेमाल किया गया है
बेहतरीन सुविधाएँ शामिल हैं.
Inheritance
आपके पास class
कीवर्ड का इस्तेमाल करके, Kotlin में क्लास का एलान करने का विकल्प है. निम्न में
उदाहरण के लिए, LoginFragment
, Fragment
की सब-क्लास है. आप यह संकेत दे सकते हैं कि
:
ऑपरेटर का इस्तेमाल करके, सब-क्लास और उसके पैरंट के बीच इनहेरिटेंस:
class LoginFragment : Fragment()
इस क्लास के एलान में, LoginFragment
की ज़िम्मेदारी है कि वह
इसकी सुपर क्लास, Fragment
का कंस्ट्रक्टर है.
LoginFragment
में, कई लाइफ़साइकल कॉलबैक को बदलकर,
अपने Fragment
की स्थिति में हुए बदलावों के हिसाब से कार्रवाई कर सकता है. फ़ंक्शन को बदलने के लिए,
override
कीवर्ड, जैसा कि इस उदाहरण में दिखाया गया है:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.login_fragment, container, false)
}
पैरंट क्लास में किसी फ़ंक्शन का रेफ़रंस देने के लिए, super
कीवर्ड का इस्तेमाल करें, जैसा कि दिखाया गया है
नीचे दिए गए उदाहरण में:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
शून्य होने की संभावना और इनिशलाइज़ेशन
पिछले उदाहरणों में, ओवरराइड किए गए तरीकों के कुछ पैरामीटर में
सवाल के निशान ?
से जुड़े हुए टाइप. इससे पता चलता है कि आर्ग्युमेंट
पास की गई वैल्यू शून्य हो सकती है. कृपया
उनकी शून्य होने की संभावना को सुरक्षित रूप से हल कर सकता है.
Kotlin में, आपको ऑब्जेक्ट का एलान करते समय, किसी ऑब्जेक्ट की प्रॉपर्टी शुरू करनी होंगी.
इसका मतलब है कि जब आपको किसी क्लास का इंस्टेंस मिलता है, तो
उसमें अपनी ऐक्सेस की जा सकने वाली प्रॉपर्टी का रेफ़रंस शामिल करें. Fragment
में View
ऑब्जेक्ट,
हालांकि, Fragment#onCreateView
को कॉल करने तक, ये वैल्यू बढ़ाई नहीं जा सकतीं. इसलिए,
आपको View
के लिए प्रॉपर्टी शुरू करने की प्रोसेस को टालने का तरीका चाहिए.
lateinit
की मदद से, प्रॉपर्टी शुरू करने में देरी हो सकती है. lateinit
का इस्तेमाल करते समय,
तो आपको अपनी प्रॉपर्टी जल्द से जल्द शुरू करनी चाहिए.
इस उदाहरण में, View
ऑब्जेक्ट असाइन करने के लिए, lateinit
का इस्तेमाल करने के बारे में बताया गया है
onViewCreated
:
class LoginFragment : Fragment() {
private lateinit var usernameEditText: EditText
private lateinit var passwordEditText: EditText
private lateinit var loginButton: Button
private lateinit var statusTextView: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
usernameEditText = view.findViewById(R.id.username_edit_text)
passwordEditText = view.findViewById(R.id.password_edit_text)
loginButton = view.findViewById(R.id.login_button)
statusTextView = view.findViewById(R.id.status_text_view)
}
...
}
एसएएम कन्वर्ज़न
Android में क्लिक इवेंट सुनने के लिए,
OnClickListener
इंटरफ़ेस. Button
ऑब्जेक्ट में setOnClickListener()
है
फ़ंक्शन है, जो OnClickListener
को लागू करता है.
OnClickListener
में onClick()
का एक ऐब्स्ट्रैक्ट तरीका है, जो आपको
लागू करें. क्योंकि setOnClickListener()
हमेशा OnClickListener
को
एक तर्क दिया गया है और क्योंकि OnClickListener
में हमेशा एक ही ऐब्स्ट्रैक्ट होता है
विधि है, तो इस कार्यान्वयन को
Kotlin. इस प्रक्रिया को
एक ऐब्स्ट्रैक्ट तरीके का कन्वर्ज़न,
या एसएएम कन्वर्ज़न.
एसएएम कन्वर्ज़न आपके कोड को काफ़ी साफ़-सुथरा बना सकता है. यह उदाहरण
दिखाता है कि एसएएम कन्वर्ज़न का इस्तेमाल करके,OnClickListener
Button
:
loginButton.setOnClickListener {
val authSuccessful: Boolean = viewModel.authenticate(
usernameEditText.text.toString(),
passwordEditText.text.toString()
)
if (authSuccessful) {
// Navigate to next screen
} else {
statusTextView.text = requireContext().getString(R.string.auth_failed)
}
}
अनाम फ़ंक्शन का कोड setOnClickListener()
को पास किया गया
तब लागू होता है, जब कोई उपयोगकर्ता loginButton
पर क्लिक करता है.
कंपैनियन ऑब्जेक्ट
कंपैनियन ऑब्जेक्ट
लिंक किए गए वैरिएबल या फ़ंक्शन को परिभाषित करने का तरीका उपलब्ध कराते हैं
एक टाइप के लिए, लेकिन किसी खास ऑब्जेक्ट से नहीं जुड़े होते. कंपैनियन
ऑब्जेक्ट और वैरिएबल और मेथड के लिए, Java के static
कीवर्ड का इस्तेमाल करने की तरह ही काम करते हैं.
यहां दिए गए उदाहरण में, TAG
एक String
कॉन्सटेंट है. आपको यूनीक
LoginFragment
के हर इंस्टेंस के लिए String
का इंस्टेंस चाहिए, इसलिए आपको यह करना चाहिए
इसे किसी कंपैनियन ऑब्जेक्ट में परिभाषित करें:
class LoginFragment : Fragment() {
...
companion object {
private const val TAG = "LoginFragment"
}
}
आप फ़ाइल के टॉप लेवल पर TAG
तय कर सकते हैं, लेकिन
फ़ाइल में कई वैरिएबल, फ़ंक्शन, और क्लास
जो टॉप लेवल पर भी तय किए गए हों. कंपैनियन ऑब्जेक्ट से कनेक्ट करने में मदद मिलती है
बिना किसी रेफ़रंस के वैरिएबल, फ़ंक्शन, और क्लास की परिभाषा
डालें.
प्रॉपर्टी का ऐक्सेस देना
प्रॉपर्टी शुरू करते समय, हो सकता है कि आप Android के कुछ सामान्य
पैटर्न, जैसे कि Fragment
में ViewModel
ऐक्सेस करना. ज़्यादा पैसे खर्च करने से बचने के लिए
तो आप Kotlin के प्रॉपर्टी डेलिगेशन सिंटैक्स का इस्तेमाल कर सकते हैं.
private val viewModel: LoginViewModel by viewModels()
प्रॉपर्टी डेलिगेशन एक सामान्य तरीका उपलब्ध कराता है, जिसका इस्तेमाल फिर से किया जा सकता है
ट्रैक करें. Android KTX आपको कुछ प्रॉपर्टी डेलिगेट की सुविधा देता है.
उदाहरण के लिए, viewModels
, ऐसे ViewModel
को हासिल करता है जो
मौजूदा Fragment
.
प्रॉपर्टी डेलिगेशन में रिफ़्लेक्शन का इस्तेमाल होता है, जिससे परफ़ॉर्मेंस का कुछ हिस्सा बढ़ जाता है. ट्रेडऑफ़ एक छोटा सिंटैक्स है, जिससे डेवलपमेंट का समय बचता है.
शून्य होने की क्षमता
Kotlin, शून्य करने के सख्त नियम के बारे में बताती है, जो पूरे टाइप-सुरक्षा को बनाए रखती है
आपका ऐप्लिकेशन. Kotlin में, ऑब्जेक्ट के रेफ़रंस में शून्य वैल्यू नहीं हो सकतीं
डिफ़ॉल्ट. किसी वैरिएबल के लिए शून्य वैल्यू असाइन करने के लिए, आपको शून्य वैल्यू के तौर पर एलान करना होगा
वैरिएबल टाइप को बेस टाइप के आखिर में ?
जोड़कर.
उदाहरण के लिए, Kotlin में यह एक्सप्रेशन गैर-कानूनी है. name
इस तरह का है
String
और इसे शून्य नहीं किया जा सकता:
val name: String = null
शून्य वैल्यू की अनुमति देने के लिए, आपको शून्य करने लायक String
टाइप, String?
का इस्तेमाल इस तरह करना होगा
नीचे दिए गए उदाहरण में दिखाया गया है:
val name: String? = null
इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना)
Kotlin के सख्त नियम, आपके कोड को ज़्यादा सुरक्षित और कम अवधि का बनाते हैं. ये नियम कम हो जाते हैं
NullPointerException
होने की संभावना कम है. इसकी वजह से आपका ऐप्लिकेशन
बंद करना. इसके अलावा, वे शून्य चेक की संख्या को कम कर देती हैं.
कोड.
अक्सर, आपको Android ऐप्लिकेशन लिखते समय गैर-Kotlin कोड में भी कॉल करना होगा, जैसे ज़्यादातर Android API, Java प्रोग्रामिंग भाषा में लिखे जाते हैं.
शून्य, एक ऐसा अहम इलाका है जहां Java और Kotlin के काम करने का तरीका अलग-अलग होता है. Java का इस्तेमाल कम किया जाता है शून्यता सिंटैक्स के साथ सख्त.
उदाहरण के लिए, Account
क्लास में कुछ प्रॉपर्टी हैं. इनमें String
भी शामिल है
प्रॉपर्टी का नाम name
है. Java में शून्य की क्षमता से जुड़े Kotlin के नियम नहीं हैं,
इसके बजाय, साफ़ तौर पर इसकी जानकारी देने के लिए, शून्य वैल्यू होने के वैकल्पिक एनोटेशन पर भरोसा किया जाता है
शून्य वैल्यू असाइन कर सकते हैं या नहीं.
Android फ़्रेमवर्क को मुख्य रूप से Java में लिखा जाता है. इसलिए, आपके पास शून्य होने की संभावना वाले एनोटेशन के बिना एपीआई में कॉल करते समय, यह उदाहरण देखें.
प्लैटफ़ॉर्म के टाइप
अगर आप किसी ऐसे name
सदस्य का रेफ़रंस देने के लिए Kotlin का इस्तेमाल करते हैं जिसकी व्याख्या नहीं की गई है, तो
Java की Account
क्लास का इस्तेमाल करते समय, कंपाइलर को यह नहीं पता होता कि String
Kotlin में String
या String?
. इस अस्पष्टता को
platform type, String!
.
String!
का Kotlin कंपाइलर के लिए कोई खास मतलब नहीं होता है. String!
ने प्रतिनिधि के तौर पर
कोई String
या String?
होता है और कंपाइलर से आपको
कोई भी टाइप करें. ध्यान रखें कि आपको NullPointerException
फेंकने का जोखिम होता है, अगर
टाइप को String
के तौर पर दिखाएं और शून्य वैल्यू असाइन करें.
इस समस्या को हल करने के लिए, लिखते समय शून्य होने वाली जानकारी का इस्तेमाल करना चाहिए में कोड हो सकते हैं. इन एनोटेशन से Java और Kotlin डेवलपर, दोनों को मदद मिलती है.
उदाहरण के लिए, यहां Account
क्लास दी गई है, जैसा कि इसे Java में तय किया गया है:
public class Account implements Parcelable {
public final String name;
public final String type;
private final @Nullable String accessId;
...
}
सदस्य वैरिएबल में से एक, accessId
, @Nullable
के साथ एनोटेट किया गया है,
यह बताता है कि इसमें शून्य वैल्यू हो सकती है. इसके बाद, Kotlin accessId
का इस्तेमाल करेगी
String?
के तौर पर.
यह बताने के लिए कि वैरिएबल कभी भी शून्य नहीं हो सकता, @NonNull
एनोटेशन का इस्तेमाल करें:
public class Account implements Parcelable {
public final @NonNull String name;
...
}
इस स्थिति में, Kotlin में name
को शून्य नहीं किया जा सकने वाला String
माना जाता है.
शून्य एट्रिब्यूट वाले एनोटेशन, सभी नए Android API और कई मौजूदा एपीआई में शामिल किए जाते हैं Android API. कई Java लाइब्रेरी ने, शून्य वाले होने के एनोटेशन को बेहतर तरीके से जोड़ा है Kotlin और Java डेवलपर, दोनों के साथ काम करते हैं.
शून्य होने की क्षमता को मैनेज करना
अगर आप Java के प्रकार को लेकर पक्का नहीं हैं, तो आपको इसे शून्य के लायक मानना चाहिए.
उदाहरण के लिए, Account
क्लास के name
सदस्य के बारे में जानकारी नहीं दी गई है. इसलिए, आपको
यह मान लिया जाना चाहिए कि यह शून्य होने लायक String
है.
अगर आपको name
को ट्रिम करना है, ताकि उसकी वैल्यू में सबसे पहले या
खाली सफ़ेद जगह के बाद, Kotlin के trim
फ़ंक्शन का इस्तेमाल किया जा सकता है. आपके पास
String?
को अलग-अलग तरीकों से आज़माएं. इनमें से एक तरीका यह है कि not-null का इस्तेमाल करें
दावा ऑपरेटर, !!
, जैसा कि इस उदाहरण में दिखाया गया है:
val account = Account("name", "type")
val accountName = account.name!!.trim()
!!
ऑपरेटर अपनी बाईं ओर मौजूद सभी चीज़ों को शून्य के बराबर नहीं मानता है, इसलिए
इस मामले में, आप name
को गैर-शून्य String
मान रहे हैं. अगर किसी बदलाव की वजह से
एक्सप्रेशन खाली है, तो आपका ऐप्लिकेशन NullPointerException
दिखाता है.
यह ऑपरेटर तेज़ी से और आसानी से काम करता है, लेकिन इसका कम से कम इस्तेमाल किया जाना चाहिए, क्योंकि
अपने कोड में NullPointerException
के इंस्टेंस फिर से शामिल करें.
सुरक्षित कॉल ऑपरेटर, ?.
का इस्तेमाल करना ज़्यादा सुरक्षित विकल्प है, जैसा कि
नीचे दिया गया उदाहरण:
val account = Account("name", "type")
val accountName = account.name?.trim()
सुरक्षित-कॉल ऑपरेटर का इस्तेमाल करने पर, अगर name
शून्य नहीं है, तो
name?.trim()
नाम की एक वैल्यू है, जिसकी शुरुआत में या आखिर में खाली सफ़ेद जगह नहीं होती. अगर आपने
name
शून्य है, तो name?.trim()
का नतीजा null
होता है. इसका मतलब है कि
इस स्टेटमेंट को चलाने पर, आपका ऐप्लिकेशन कभी भी NullPointerException
नहीं फेंक सकता.
हालांकि, सुरक्षित कॉल ऑपरेटर आपको संभावित NullPointerException
से बचाता है, लेकिन
यह अगले स्टेटमेंट के लिए शून्य वैल्यू पास करता है. इसके बजाय आप शून्य को हैंडल कर सकते हैं
Elvis ऑपरेटर (?:
) का इस्तेमाल करके ऐसे मामले तुरंत लागू कर दिए जाते हैं, जैसा कि नीचे दिखाया गया है
उदाहरण:
val account = Account("name", "type")
val accountName = account.name?.trim() ?: "Default name"
यदि एल्विस ऑपरेटर के बाईं ओर के एक्सप्रेशन का परिणाम
खाली है, तो दाईं ओर मौजूद वैल्यू accountName
को असाइन कर दी जाती है. यह
तकनीक इस्तेमाल करके डिफ़ॉल्ट वैल्यू दी जा सकती है, जो शून्य हो सकती है.
फ़ंक्शन से जल्दी वापस आने के लिए, एल्विस ऑपरेटर का इस्तेमाल भी किया जा सकता है, जैसा कि नीचे दिखाया गया है नीचे दिए गए उदाहरण में:
fun validateAccount(account: Account?) {
val accountName = account?.name?.trim() ?: "Default name"
// account cannot be null beyond this point
account ?: return
...
}
Android API से जुड़े बदलाव
Android के एपीआई, Kotlin के लिए काफ़ी मददगार होते जा रहे हैं. Android के कई
AppCompatActivity
और Fragment
सहित ज़्यादातर सामान्य एपीआई में,
अमान्य एनोटेशन और Fragment#getContext
जैसे कुछ कॉल में
Kotlin-फ़्रेंडली विकल्प.
उदाहरण के लिए, Fragment
के Context
का इस्तेमाल करना हमेशा शून्य नहीं होता है,
क्योंकि Fragment
में ज़्यादातर कॉल किए जाते हैं, जबकि Fragment
एक Activity
(Context
की सब-क्लास) से अटैच है. हालांकि,
Fragment#getContext
हमेशा ऐसी वैल्यू नहीं दिखाता जो शून्य नहीं होती, क्योंकि ऐसी वैल्यू होती हैं
ऐसे मामले जहां Fragment
, Activity
के साथ अटैच नहीं होता. इस तरह, रिटर्न
Fragment#getContext
का टाइप अमान्य है.
Fragment#getContext
से रिस्पॉन्स के तौर पर मिला Context
अमान्य है (और यह है
@Nullable के तौर पर एनोटेट किया गया है), तो आपको अपने Kotlin कोड में इसे Context?
के तौर पर मानना होगा.
इसका मतलब है कि आईपी पते के लिए, ऊपर बताए गए किसी ऑपरेटर को लागू करना
अमान्य वैल्यू मिल जाएगी. इनमें से कुछ के लिए
की तरह, Android में यह सुविधा देने वाले वैकल्पिक एपीआई शामिल हैं.
उदाहरण के लिए, Fragment#requireContext
, शून्य के अलावा Context
दिखाता है और थ्रो
एक IllegalStateException
, अगर Context
के शून्य होने पर कॉल किया जाता है. इस तरह,
तो आप नतीजे के तौर पर मिलने वाले Context
को बिना शून्य के मान सकते हैं
सुरक्षित कॉल ऑपरेटर या समाधान.
प्रॉपर्टी शुरू करना
Kotlin में प्रॉपर्टी डिफ़ॉल्ट रूप से शुरू नहीं होती हैं. इन्हें शुरू किया जाना चाहिए जब उनकी एनक्लोज़िंग क्लास शुरू होती है.
प्रॉपर्टी को अलग-अलग तरीकों से शुरू किया जा सकता है. यह उदाहरण
यह दिखाता है कि किसी index
वैरिएबल को कैसे शुरू किया जाए. इसके लिए,
क्लास का एलान:
class LoginFragment : Fragment() {
val index: Int = 12
}
इस प्रोसेस को इनिशलाइज़र ब्लॉक में भी तय किया जा सकता है:
class LoginFragment : Fragment() {
val index: Int
init {
index = 12
}
}
ऊपर दिए गए उदाहरण में, index
तब शुरू होता है, जब LoginFragment
बनाया गया.
हालांकि, आपके पास कुछ ऐसी प्रॉपर्टी हो सकती हैं जिन्हें ऑब्जेक्ट के दौरान शुरू नहीं किया जा सकता
निर्माण. उदाहरण के लिए, हो सकता है कि आपView
Fragment
का मतलब है कि लेआउट को पहले इनफ़्लेट किया जाना चाहिए. मुद्रास्फीति यह करती है
Fragment
के बनाए जाने पर नहीं होता है. इसके बजाय, कॉल करते समय यह बढ़ जाता है
Fragment#onCreateView
.
इस स्थिति को ठीक करने का एक तरीका यह है कि आप व्यू को शून्य के लायक के तौर पर दिखाएं और इसे जल्द से जल्द शुरू करें, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:
class LoginFragment : Fragment() {
private var statusTextView: TextView? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
statusTextView = view.findViewById(R.id.status_text_view)
statusTextView?.setText(R.string.auth_failed)
}
}
हालांकि, यह उम्मीद के मुताबिक काम करता है, लेकिन अब आपको View
के शून्य होने की स्थिति को मैनेज करना होगा
रेफ़रंस के तौर पर सेव करें. View
के लिए lateinit
का इस्तेमाल करना एक बेहतर समाधान है
शुरू करना, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:
class LoginFragment : Fragment() {
private lateinit var statusTextView: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
statusTextView = view.findViewById(R.id.status_text_view)
statusTextView.setText(R.string.auth_failed)
}
}
lateinit
कीवर्ड की मदद से, प्रॉपर्टी शुरू करने से बचा जा सकता है. ऐसा तब होगा, जब
ऑब्जेक्ट बनाया जाता है. अगर शुरू करने से पहले आपकी प्रॉपर्टी का रेफ़रंस दिया गया है,
Kotlin UninitializedPropertyAccessException
थ्रो करता है, इसलिए पक्का करें कि
अपनी प्रॉपर्टी को जल्द से जल्द शुरू करें.