Android KTX का हिस्सा है Android Jetpack.
Android KTX, Kotlin एक्सटेंशन का एक सेट है. यह Android Jetpack और Android की अन्य लाइब्रेरी के साथ शामिल होता है. KTX एक्सटेंशन, Jetpack, Android प्लैटफ़ॉर्म, और अन्य एपीआई के लिए, Kotlin के संक्षिप्त और इडियोमैटिक कोड उपलब्ध कराते हैं. ऐसा करने के लिए, इन एक्सटेंशन में Kotlin की कई सुविधाओं का इस्तेमाल किया जाता है. इनमें ये शामिल हैं:
- एक्सटेंशन फ़ंक्शन
- एक्सटेंशन प्रॉपर्टी
- Lambdas
- नाम वाले पैरामीटर
- पैरामीटर की डिफ़ॉल्ट वैल्यू
- कोरूटीन
उदाहरण के लिए, SharedPreferencesके साथ काम करते समय, आपको
एक एडिटर बनाना होगा
इससे पहले कि आप प्राथमिकताओं के डेटा में बदलाव कर सकें. आपको बदलाव करने के बाद, उन बदलावों को लागू या कमिट भी करना होगा. जैसा कि इस उदाहरण में दिखाया गया है:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Kotlin lambdas, इस इस्तेमाल के उदाहरण के लिए बिलकुल सही हैं. इनकी मदद से, एडिटर बनाने के बाद कोड का एक ब्लॉक पास करके, उसे एक्ज़ीक्यूट किया जा सकता है. इससे कोड एक्ज़ीक्यूट होता है और फिर SharedPreferences API, बदलावों को एटॉमिक तरीके से लागू करता है.
यहां Android KTX के मुख्य फ़ंक्शन में से एक का उदाहरण दिया गया है,
SharedPreferences.edit,
जो SharedPreferences में बदलाव करने वाला फ़ंक्शन जोड़ता है. यह फ़ंक्शन, पहले आर्ग्युमेंट के तौर पर एक वैकल्पिक boolean फ़्लैग लेता है. इससे यह पता चलता है कि बदलावों को कमिट करना है या लागू करना है. साथ ही, यह lambda के तौर पर, SharedPreferences एडिटर पर की जाने वाली कार्रवाई को भी लेता है.
// SharedPreferences.edit extension function signature from Android KTX - Core
// inline fun SharedPreferences.edit(
// commit: Boolean = false,
// action: SharedPreferences.Editor.() -> Unit)
// Commit a new value asynchronously
sharedPreferences.edit { putBoolean("key", value) }
// Commit a new value synchronously
sharedPreferences.edit(commit = true) { putBoolean("key", value) }
कॉल करने वाले के पास यह चुनने का विकल्प होता है कि बदलावों को कमिट करना है या लागू करना है. action lambda, SharedPreferences.Editor पर एक पहचान छिपाने वाला एक्सटेंशन फ़ंक्शन है. यह Unit रिटर्न करता है, जैसा कि इसके सिग्नेचर से पता चलता है. इसलिए, ब्लॉक के अंदर, सीधे काम किया जा सकता है
SharedPreferences.Editor.
आखिर में, SharedPreferences.edit() के सिग्नेचर में inline कीवर्ड शामिल होता है.
इस कीवर्ड से Kotlin कंपाइलर को यह पता चलता है कि फ़ंक्शन का इस्तेमाल किए जाने पर, उसे कंपाइल किए गए बाइटकोड को कॉपी और पेस्ट (या इनलाइन) करना चाहिए.
इससे, हर बार इस फ़ंक्शन को कॉल किए जाने पर, हर action के लिए नई क्लास का इंस्टेंस बनाने का ओवरहेड कम हो जाता है.
lambda का इस्तेमाल करके कोड पास करने, डिफ़ॉल्ट वैल्यू लागू करने, और inline एक्सटेंशन फ़ंक्शन का इस्तेमाल करके मौजूदा एपीआई में इन व्यवहारों को जोड़ने का पैटर्न, Android KTX लाइब्रेरी से मिलने वाले बेहतर बनाने के तरीकों की खासियत है.
अपने प्रोजेक्ट में Android KTX का इस्तेमाल करना
Android KTX का इस्तेमाल शुरू करने के लिए, अपने प्रोजेक्ट की build.gradle फ़ाइल में यह डिपेंडेंसी जोड़ें:
शानदार
repositories { google() }
Kotlin
repositories { google() }
AndroidX मॉड्यूल
Android KTX को मॉड्यूल में व्यवस्थित किया गया है. हर मॉड्यूल में एक या उससे ज़्यादा पैकेज होते हैं.
आपको अपने ऐप्लिकेशन की build.gradle फ़ाइल में, हर मॉड्यूल आर्टफ़ैक्ट के लिए एक डिपेंडेंसी शामिल करनी होगी. आर्टफ़ैक्ट में वर्शन नंबर जोड़ना न भूलें.
इस विषय में, हर आर्टफ़ैक्ट के सेक्शन में, सबसे नए वर्शन नंबर देखे जा सकते हैं.
Android KTX में एक मुख्य मॉड्यूल होता है. इसमें सामान्य फ़्रेमवर्क एपीआई और डोमेन के हिसाब से कई एक्सटेंशन के लिए, Kotlin एक्सटेंशन शामिल होते हैं.
मुख्य मॉड्यूल को छोड़कर, सभी KTX मॉड्यूल आर्टफ़ैक्ट, आपकी build.gradle फ़ाइल में मौजूद Java की डिपेंडेंसी की जगह लेते हैं. उदाहरण के लिए, आप
एक androidx.fragment:fragment डिपेंडेंसी को
androidx.fragment:fragment-ktx से बदल सकते हैं. इस सिंटैक्स से वर्शनिंग को बेहतर तरीके से मैनेज करने में मदद मिलती है. साथ ही, इससे डिपेंडेंसी के एलान से जुड़ी अतिरिक्त ज़रूरतें नहीं जुड़ती हैं.
Core KTX
Core KTX मॉड्यूल, Android फ़्रेमवर्क का हिस्सा बनने वाली सामान्य लाइब्रेरी के लिए एक्सटेंशन उपलब्ध कराता है. इन लाइब्रेरी में Java पर आधारित डिपेंडेंसी नहीं होती हैं. इसलिए, इन्हें build.gradle में जोड़ने की ज़रूरत नहीं होती.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.18.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.18.0") }
यहां उन पैकेज की सूची दी गई है जो Core KTX मॉड्यूल में शामिल हैं:
- androidx.core.animation
- androidx.core.content
- androidx.core.content.res
- androidx.core.database
- androidx.core.database.sqlite
- androidx.core.graphics
- androidx.core.graphics.drawable
- androidx.core.location
- androidx.core.net
- androidx.core.os
- androidx.core.text
- androidx.core.transition
- androidx.core.util
- androidx.core.view
- androidx.core.widget
Collection KTX
Collection एक्सटेंशन में, Android की मेमोरी-एफ़िशिएंट कलेक्शन लाइब्रेरी के साथ काम करने के लिए यूटिलिटी फ़ंक्शन शामिल होते हैं. इनमें ArrayMap, LongSparseArray, LruCache वगैरह शामिल हैं.
इस मॉड्यूल का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.collection:collection-ktx:1.6.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.6.0") }
Collection एक्सटेंशन, Kotlin के ऑपरेटर ओवरलोडिंग का फ़ायदा उठाते हैं. इससे कलेक्शन को जोड़ना जैसे काम आसान हो जाते हैं. जैसा कि इस उदाहरण में दिखाया गया है:
// Combine 2 ArraySets into 1.
val combinedArraySet = arraySetOf(1, 2, 3) + arraySetOf(4, 5, 6)
// Combine with numbers to create a new sets.
val newArraySet = combinedArraySet + 7 + 8
Fragment KTX
The Fragment KTX module फ़्रैगमेंट एपीआई को आसान बनाने के लिए कई एक्सटेंशन उपलब्ध कराता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
ग्रूवी
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.9" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.9") }
Fragment KTX मॉड्यूल की मदद से, फ़्रैगमेंट ट्रांज़ैक्शन को lambdas की मदद से आसान बनाया जा सकता है. उदाहरण के लिए:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
ViewModel को एक लाइन में भी बाइंड किया जा सकता है: viewModels और
activityViewModels प्रॉपर्टी डेलिगेट का इस्तेमाल करके,
// Get a reference to the ViewModel scoped to this Fragment
val viewModel by viewModels<MyViewModel>()
// Get a reference to the ViewModel scoped to its Activity
val viewModel by activityViewModels<MyViewModel>()
Lifecycle KTX
Lifecycle KTX, हर
Lifecycle ऑब्जेक्ट के लिए एक LifecycleScope तय करता है. जब Lifecycle मिट जाता है, तब इस स्कोप में लॉन्च किया गया कोई भी कोरूटीन रद्द हो जाता है. lifecycle.coroutineScope या lifecycleOwner.lifecycleScope प्रॉपर्टी का इस्तेमाल करके, Lifecycle के CoroutineScope को ऐक्सेस किया जा सकता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.10.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.10.0") }
इस उदाहरण में, एसिंक्रोनस तरीके से पहले से तैयार किया गया टेक्स्ट बनाने के लिए, lifecycleOwner.lifecycleScope का इस्तेमाल करने का तरीका बताया गया है:
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
val params = TextViewCompat.getTextMetricsParams(textView)
val precomputedText = withContext(Dispatchers.Default) {
PrecomputedTextCompat.create(longTextContent, params)
}
TextViewCompat.setPrecomputedText(textView, precomputedText)
}
}
}
LiveData KTX
LiveData का इस्तेमाल करते समय, आपको एसिंक्रोनस तरीके से वैल्यू की गिनती करनी पड़ सकती है. उदाहरण के लिए, हो सकता है कि आपको उपयोगकर्ता की प्राथमिकताएं वापस पाने और उन्हें अपने यूज़र इंटरफ़ेस (यूआई) पर दिखाना हो. ऐसे मामलों के लिए, LiveData KTX एक liveData बिल्डर फ़ंक्शन उपलब्ध कराता है. यह suspend फ़ंक्शन को कॉल करता है और नतीजे को LiveData ऑब्जेक्ट के तौर पर दिखाता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.10.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.10.0") }
इस उदाहरण में, loadUser() एक सस्पेंड फ़ंक्शन है, जिसे कहीं और एलान किया गया है.
liveData बिल्डर फ़ंक्शन का इस्तेमाल करके, loadUser() को एसिंक्रोनस तरीके से कॉल किया जा सकता है. इसके बाद, नतीजे को दिखाने के लिए emit() का इस्तेमाल किया जा सकता है:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
LiveData के साथ कोरूटीन का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, आर्किटेक्चर कॉम्पोनेंट के साथ Kotlin कोरूटीन इस्तेमाल करना लेख पढ़ें.
Navigation KTX
नेविगेशन लाइब्रेरी के हर कॉम्पोनेंट का अपना KTX वर्शन होता है. यह एपीआई को ज़्यादा संक्षिप्त और Kotlin-इडियोमैटिक बनाने के लिए अडैप्ट करता है.
इन मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.9.8" implementation "androidx.navigation:navigation-fragment-ktx:2.9.8" implementation "androidx.navigation:navigation-ui-ktx:2.9.8" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.9.8") implementation("androidx.navigation:navigation-fragment-ktx:2.9.8") implementation("androidx.navigation:navigation-ui-ktx:2.9.8") }
डेस्टिनेशन के आर्ग्युमेंट को ऐक्सेस करने और डेस्टिनेशन पर नेविगेट करने के लिए, एक्सटेंशन फ़ंक्शन और प्रॉपर्टी डेलिगेशन का इस्तेमाल करें. जैसा कि इस उदाहरण में दिखाया गया है:
class MyDestination : Fragment() {
// Type-safe arguments are accessed from the bundle.
val args by navArgs<MyDestinationArgs>()
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.next)
.setOnClickListener {
// Fragment extension added to retrieve a NavController from
// any destination.
findNavController().navigate(R.id.action_to_next_destination)
}
}
...
}
Palette KTX
The Palette KTX मॉड्यूल , कलर पैलेट के साथ काम करने के लिए, Kotlin की इडियोमैटिक सहायता उपलब्ध कराता है.
इस मॉड्यूल का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
ग्रूवी
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
उदाहरण के लिए, Palette इंस्टेंस के साथ काम करते समय, दिए गए target के लिए selected स्वॉच को पाने के लिए, get ऑपरेटर ([ ]) का इस्तेमाल किया जा सकता है:
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reactive Streams KTX
Reactive Streams KTX मॉड्यूल की मदद से, ReactiveStreams पब्लिशर से, दिखने वाला LiveData स्ट्रीम बनाया जा सकता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.10.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.10.0") }
उदाहरण के लिए, मान लें कि किसी डेटाबेस में उपयोगकर्ताओं की एक छोटी सूची है. अपने ऐप्लिकेशन में, डेटाबेस को मेमोरी में लोड करें और फिर अपने यूज़र इंटरफ़ेस (यूआई) में उपयोगकर्ता का डेटा दिखाएं. ऐसा करने के लिए, RxJava का इस्तेमाल किया जा सकता है.
Room Jetpack कॉम्पोनेंट, उपयोगकर्ता की सूची को Flowable के तौर पर वापस पा सकता है. इस स्थिति में, आपको अपने फ़्रैगमेंट या ऐक्टिविटी की लाइफ़साइकल के दौरान, Rx पब्लिशर की सदस्यता को भी मैनेज करना होगा.
हालांकि, LiveDataReactiveStreams की मदद से, RxJava और इसके
ऑपरेटरों के सेट और वर्क-शेड्यूलिंग की क्षमताओं का फ़ायदा उठाया जा सकता है. साथ ही, LiveData की सादगी के साथ काम किया जा सकता है. जैसा कि इस उदाहरण में दिखाया गया है:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Room KTX
Room एक्सटेंशन, डेटाबेस ट्रांज़ैक्शन के लिए कोरूटीन की सुविधा जोड़ते हैं.
इस मॉड्यूल का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
ग्रूवी
dependencies { implementation "androidx.room:room-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.8.4") }
यहां कुछ उदाहरण दिए गए हैं, जिनमें Room अब कोरूटीन का इस्तेमाल करता है. पहले उदाहरण
में, suspend ऑब्जेक्ट की सूची को वापस पाने के लिए, User फ़ंक्शन का इस्तेमाल किया गया है. वहीं, दूसरे उदाहरण
में, User की सूची को एसिंक्रोनस तरीके से वापस पाने के लिए, Kotlin के Flow
का इस्तेमाल किया गया है. ध्यान दें कि Flow का इस्तेमाल करते समय, आपको उन टेबल में किए गए किसी भी बदलाव के बारे में सूचना मिलती है जिनकी क्वेरी की जा रही है.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
SQLite एक्सटेंशन, SQL से जुड़े कोड को ट्रांज़ैक्शन में रैप करते हैं. इससे, छोटे-मोटे बदलाव वाले कई कोड की ज़रूरत नहीं पड़ती.
इस मॉड्यूल का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.6.2") }
यहां डेटाबेस ट्रांज़ैक्शन करने के लिए, transaction एक्सटेंशन का इस्तेमाल करने का एक उदाहरण दिया गया है:
db.transaction {
// insert data
}
ViewModel KTX
ViewModel KTX लाइब्रेरी, viewModelScope() फ़ंक्शन उपलब्ध कराती है. इससे
अपने ViewModel से कोरूटीन लॉन्च करना आसान हो जाता है. The
CoroutineScope
से बाउंड होता है. साथ ही, ViewModel के मिटने पर यह अपने-आप रद्द हो जाता है.Dispatchers.Main हर ViewModel के लिए नया स्कोप बनाने के बजाय, viewModelScope() का इस्तेमाल किया जा सकता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0") }
उदाहरण के लिए, यहां दिया गया viewModelScope() फ़ंक्शन, एक कोरूटीन लॉन्च करता है. यह बैकग्राउंड थ्रेड में नेटवर्क अनुरोध करता है. लाइब्रेरी, सेटअप और उससे जुड़े स्कोप को मिटाने का काम करती है:
class MainViewModel : ViewModel() {
// Make a network request without blocking the UI thread
private fun makeNetworkRequest() {
// launch a coroutine in viewModelScope
viewModelScope.launch {
remoteApi.slowFetch()
...
}
}
// No need to override onCleared()
}
WorkManager KTX
WorkManager KTX, कोरूटीन के लिए बेहतर सहायता उपलब्ध कराता है.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
ग्रूवी
dependencies { implementation "androidx.work:work-runtime-ktx:2.11.2" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.11.2") }
Worker को बढ़ाने के बजाय, अब CoroutineWorker को बढ़ाया जा सकता है.
इसमें थोड़ा अलग एपीआई होता है. उदाहरण के लिए, अगर आपको कुछ नेटवर्क कार्रवाइयां करने के लिए, एक आसान CoroutineWorker बनाना है, तो यह तरीका अपनाएं:
class CoroutineDownloadWorker(context: Context, params: WorkerParameters)
: CoroutineWorker(context, params) {
override suspend fun doWork(): Result = coroutineScope {
val jobs = (0 until 100).map {
async {
downloadSynchronously("https://www.google.com")
}
}
// awaitAll will throw an exception if a download fails, which
// CoroutineWorker will treat as a failure
jobs.awaitAll()
Result.success()
}
}
CoroutineWorker का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, CoroutineWorker में थ्रेडिंग लेख पढ़ें.
WorkManager KTX, मौजूदा कोरूटीन को सस्पेंड करने के लिए, Operations और ListenableFutures में एक्सटेंशन फ़ंक्शन भी जोड़ता है.
यहां एक उदाहरण दिया गया है, जिसमें
Operation से मिले
enqueue() को सस्पेंड किया गया है:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
अन्य KTX मॉड्यूल
AndroidX के बाहर मौजूद अन्य KTX मॉड्यूल भी शामिल किए जा सकते हैं.
Firebase KTX
Android के लिए Firebase SDK टूल में से कुछ में, Kotlin एक्सटेंशन लाइब्रेरी होती हैं. इनकी मदद से, अपने ऐप्लिकेशन में Firebase का इस्तेमाल करते समय, Kotlin का इडियोमैटिक कोड लिखा जा सकता है. ज़्यादा जानकारी के लिए, ये लेख पढ़ें:
Google Maps Platform KTX
Google Maps Platform के Android SDK टूल के लिए, KTX एक्सटेंशन उपलब्ध हैं. इनकी मदद से, Kotlin की कई सुविधाओं का फ़ायदा उठाया जा सकता है. जैसे, एक्सटेंशन फ़ंक्शन, नाम वाले पैरामीटर और डिफ़ॉल्ट आर्ग्युमेंट, डिस्ट्रक्चरिंग एलान, और कोरूटीन. ज़्यादा जानकारी के लिए, ये लेख पढ़ें:
Play Core KTX
Play Core KTX, एक बार के अनुरोधों के लिए Kotlin कोरूटीन और स्टेटस अपडेट की निगरानी के लिए Flow की सुविधा जोड़ता है. इसके लिए, Play Core लाइब्रेरी में SplitInstallManager और AppUpdateManager में एक्सटेंशन फ़ंक्शन जोड़े जाते हैं.
इस मॉड्यूल को शामिल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में यह जोड़ें:
शानदार
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Kotlin
dependencies { implementation("com.google.android.play:core-ktx:1.8.1") }
यहां स्टेटस की निगरानी करने वाले Flow का एक उदाहरण दिया गया है:
// Inside of a coroutine...
// Request in-app update status updates.
manager.requestUpdateFlow().collect { updateResult ->
when (updateResult) {
is AppUpdateResult.Available -> TODO()
is AppUpdateResult.InProgress -> TODO()
is AppUpdateResult.Downloaded -> TODO()
AppUpdateResult.NotAvailable -> TODO()
}
}
ज़्यादा जानकारी
Android KTX के बारे में ज़्यादा जानने के लिए, DevBytes का वीडियो देखें.
किसी समस्या की शिकायत करने या किसी सुविधा का सुझाव देने के लिए, Android KTX के समस्या ट्रैकर का इस्तेमाल करें.