Android KTX   بخشی از Android Jetpack.

‫Android KTX مجموعه‌ای از افزونه‌های Kotlin است که در Android Jetpack و دیگر کتابخانه‌های Android گنجانده شده است. افزونه‌های KTX،‏ Kotlin اصطلاحی و مختصر را برای Jetpack، پلاتفرم Android، و دیگر میاناهای برنامه‌سازی کاربردی ارائه می‌دهند. برای انجام این کار، این افزونه‌ها از چندین ویژگی زبان Kotlin استفاده می‌کنند، ازجمله:

  • توابع افزونه
  • خصوصیت‌های افزونه
  • لامبدا
  • پارامترهای نام‌گذاری‌شده
  • مقادیر پیش‌فرض پارامتر
  • روال‌های مشترک

برای مثال، هنگام کار با SharedPreferences، باید یک ویرایشگر ایجاد کنید تا بتوانید تغییراتی در داده‌های اولویت‌ها ایجاد کنید. همچنین باید پس‌از اتمام ویرایش، آن تغییرات را اعمال یا ثبت کنید، همان‌طور که در مثال زیر نشان داده شده است:

sharedPreferences
        .edit()  // create an Editor
        .putBoolean("key", value)
        .apply() // write to disk asynchronously

لامبداهای Kotlin برای این مورد استفاده کاملاً مناسب هستند. این روش‌ها به شما امکان می‌دهند با ارسال یک بلوک کد برای اجرا پس‌از ایجاد ویرایشگر، اجازه دادن به اجرای کد، و سپس اجازه دادن به میانای برنامه‌سازی کاربردی SharedPreferences برای اعمال تغییرات به‌صورت اتمی، رویکرد مختصرتری اتخاذ کنید.

در اینجا نمونه‌ای از یکی از عملکردهای Android KTX Core آورده شده است، SharedPreferences.edit، که یک عملکرد ویرایش به SharedPreferences اضافه می‌کند. این تابع یک پرچم اختیاری boolean را به‌عنوان اولین آرگومان خود می‌گیرد که نشان می‌دهد آیا تغییرات باید اعمال شوند یا خیر. همچنین کنشی برای اجرا در ویرایشگر 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 در هر بار فراخوانی این تابع جلوگیری می‌کند.

این الگو برای ارسال کد بااستفاده از لامبدا، اعمال پیش‌فرض‌های معقولی که می‌توانند لغو شوند، و افزودن این رفتارها به میاناهای برنامه‌سازی کاربردی موجود بااستفاده از inline توابع افزونه، نمونه‌ای از بهبودهای ارائه‌شده توسط کتابخانه Android KTX است.

استفاده از Android KTX در پروژه

برای شروع استفاده از Android KTX، وابستگی زیر را به فایل build.gradle پروژه‌تان اضافه کنید:

شیک

repositories {
    google()
}

کاتلین

repositories {
    google()
}

واحدهای AndroidX

Android KTX در قالب ماژول‌هایی سازمان‌دهی شده است که هر ماژول حاوی یک یا چند بسته است.

باید برای هر آرتیفکت پیمانه در فایل build.gradle برنامه‌تان، وابستگی اضافه کنید. فراموش نکنید که شماره نسخه را به آرتیفکت اضافه کنید. می‌توانید جدیدترین شماره‌های نسخه را در بخش مربوط به هر آرتیفکت در این موضوع پیدا کنید.

‫Android KTX حاوی یک واحد هسته است که افزونه‌های Kotlin را برای میاناهای برنامه‌سازی کاربردی چارچوب رایج و چندین افزونه مختص دامنه ارائه می‌دهد.

به‌استثنای واحد اصلی، همه آرتیفکت‌های واحد KTX جایگزین وابستگی جاوا در فایل build.gradle شما می‌شوند. برای مثال، می‌توانید وابستگی androidx.fragment:fragment را با androidx.fragment:fragment-ktx جایگزین کنید. این نحو به مدیریت بهتر نسخه‌بندی کمک می‌کند و الزامات اضافی برای اعلام وابستگی اضافه نمی‌کند.

Core KTX

واحد Core KTX افزونه‌هایی برای کتابخانه‌های رایج ارائه می‌دهد که بخشی از چارچوب Android هستند. این کتابخانه‌ها وابستگی‌های مبتنی بر Java ندارند که لازم باشد به build.gradle اضافه کنید.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیک

dependencies {
    implementation "androidx.core:core-ktx:1.19.1"
}

کاتلین

dependencies {
    implementation("androidx.core:core-ktx:1.19.1")
}

در اینجا فهرستی از بسته‌های موجود در ماژول Core KTX آورده شده است:

مجموعه KTX

افزونه‌های Collection حاوی توابع سودمندی برای کار با کتابخانه‌های مجموعه Android با مصرف بهینه حافظه است، ازجمله ArrayMap، LongSparseArray، LruCache، و غیره.

برای استفاده از این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیار

dependencies {
    implementation "androidx.collection:collection-ktx:1.6.0"
}

کاتلین

dependencies {
    implementation("androidx.collection:collection-ktx:1.6.0")
}

افزونه‌های مجموعه از سربارگذاری عملگر 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

ماژول Fragment KTX چندین افزونه برای ساده‌سازی Fragment API ارائه می‌دهد.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیار

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.9.1"
}

کاتلین

dependencies {
    implementation("androidx.fragment:fragment-ktx:1.9.1")
}

با پیمانه Fragment KTX، می‌توانید تراکنش‌های قطعه را با عبارت‌های لامبدا ساده کنید، برای مثال:

fragmentManager().commit {
   addToBackStack("...")
   setCustomAnimations(
           R.anim.enter_anim,
           R.anim.exit_anim)
   add(fragment, "...")
}

همچنین می‌توانید بااستفاده از نمایندگان ویژگی viewModels و activityViewModels، در یک خط به ViewModel متصل شوید:

// 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 می‌توانید به CoroutineScope مربوط به Lifecycle دسترسی پیدا کنید.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.11.0"
}

کاتلین

dependencies {
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.11.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 برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.11.0"
}

کاتلین

dependencies {
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.11.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 خودش را دارد که میانای برنامه‌سازی کاربردی را طوری تطبیق می‌دهد که مختصرتر و مطابق با اصطلاحات Kotlin باشد.

برای گنجاندن این پیمانه‌ها، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.navigation:navigation-runtime-ktx:2.10.2"
    implementation "androidx.navigation:navigation-fragment-ktx:2.10.2"
    implementation "androidx.navigation:navigation-ui-ktx:2.10.2"
}

کاتلین

dependencies {
    implementation("androidx.navigation:navigation-runtime-ktx:2.10.2")
    implementation("androidx.navigation:navigation-fragment-ktx:2.10.2")
    implementation("androidx.navigation:navigation-ui-ktx:2.10.2")
}

همان‌طور که در مثال زیر نشان داده شده است، از توابع افزونه و واگذاری ویژگی برای دسترسی به متغیرهای مستقل مقصد و پیمایش به مقصدها استفاده کنید:

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

ماژول Palette KTX پشتیبانی اصطلاحی Kotlin را برای کار با پالت‌های رنگ ارائه می‌دهد.

برای استفاده از این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیار

dependencies {
    implementation "androidx.palette:palette-ktx:1.0.0"
}

کاتلین

dependencies {
    implementation("androidx.palette:palette-ktx:1.0.0")
}

به‌عنوان مثال، هنگام کار با نمونه Palette، می‌توانید نمونه رنگ selected را برای target داده‌شده بااستفاده از اپراتور get‏ ([ ]) بازیابی کنید:

val palette = Palette.from(bitmap).generate()
val swatch = palette[target]

Reactive Streams KTX

ماژول Reactive Streams KTX به شما امکان می‌دهد یک جریان LiveData قابل‌مشاهده از ناشر ReactiveStreams ایجاد کنید.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.11.0"
}

کاتلین

dependencies {
    implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.11.0")
}

به‌عنوان مثال، پایگاه داده‌ای را با فهرست کوچکی از کاربران درنظر بگیرید. در برنامه‌تان، پایگاه داده را در حافظه بار می‌کنید و سپس داده‌های کاربر را در میانای کاربر نمایش می‌دهید. برای دستیابی به این هدف، می‌توانید از RxJava استفاده کنید. مؤلفه Jetpack Room می‌تواند فهرست کاربر را به‌عنوان Flowable بازیابی کند. در این سناریو، باید اشتراک ناشر Rx را نیز درطول عمر قطعه یا فعالیتتان مدیریت کنید.

بااین‌حال، با LiveDataReactiveStreams می‌توانید از RxJava و مجموعه غنی اپراتورها و قابلیت‌های زمان‌بندی کار آن بهره‌مند شوید و درعین‌حال با سادگی LiveData کار کنید، همان‌طور که در مثال زیر نشان داده شده است:

val fun getUsersLiveData() : LiveData<List<User>> {
    val users: Flowable<List<User>> = dao.findUsers()
    return LiveDataReactiveStreams.fromPublisher(users)
}

اتاق KTX

افزونه‌های Room پشتیبانی از روال‌های همکار را برای تراکنش‌های پایگاه داده اضافه می‌کنند.

برای استفاده از این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیار

dependencies {
    implementation "androidx.room:room-ktx:2.8.5"
}

کاتلین

dependencies {
    implementation("androidx.room:room-ktx:2.8.5")
}

در اینجا چند مثال آورده شده است که Room اکنون از کوروتین‌ها استفاده می‌کند. مثال اول از تابع suspend برای برگرداندن فهرستی از اشیاء User استفاده می‌کند، درحالی‌که مثال دوم از Flow Kotlin برای برگرداندن ناهمگام فهرست User استفاده می‌کند. توجه داشته باشید که هنگام استفاده از 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 برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.sqlite:sqlite-ktx:2.7.1"
}

کاتلین

dependencies {
    implementation("androidx.sqlite:sqlite-ktx:2.7.1")
}

در اینجا مثالی از استفاده از افزونه transaction برای انجام تراکنش پایگاه داده آورده شده است:

db.transaction {
    // insert data
}

ViewModel KTX

کتابخانه ViewModel KTX تابع viewModelScope() را ارائه می‌دهد که راه‌اندازی روال‌های همگام را از ViewModel شما آسان‌تر می‌کند. CoroutineScope به Dispatchers.Main محدود است و وقتی ViewModel پاک شود، به‌طور خودکار لغو می‌شود. می‌توانید به‌جای ایجاد دامنه جدید برای هر ViewModel، از viewModelScope() استفاده کنید.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

گرووی

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.0"
}

کاتلین

dependencies {
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.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.12.0"
}

کاتلین

dependencies {
    implementation("androidx.work:work-runtime-ktx:2.12.0")
}

به‌جای گسترش دادن 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

همچنین می‌توانید ماژول‌های KTX اضافی را که خارج از AndroidX وجود دارند اضافه کنید.

Firebase KTX

برخی‌از کیت‌های توسعه نرم‌افزار Firebase برای Android دارای کتابخانه‌های افزونه Kotlin هستند که به شما امکان می‌دهند هنگام استفاده از Firebase در برنامه‌تان، کد Kotlin اصطلاحی بنویسید. برای اطلاعات بیشتر، موضوعات زیر را ببینید:

Google Maps Platform KTX

افزونه‌های KTX برای کیت‌های توسعه نرم‌افزار Android در «پلاتفرم Google Maps» دردسترس است که به شما امکان می‌دهد از چندین ویژگی زبان Kotlin مانند توابع افزونه، پارامترهای نام‌گذاری‌شده و آرگومان‌های پیش‌فرض، اعلان‌های ساختارشکنی، و روال‌های هم‌زمان بهره ببرید. برای اطلاعات بیشتر، موضوعات زیر را ببینید:

Play Core KTX

Play Core KTX با افزودن توابع افزونه به SplitInstallManager و AppUpdateManager در کتابخانه Play Core، پشتیبانی از روال‌های هم‌زمان Kotlin را برای درخواست‌های یک‌باره و Flow برای نظارت بر به‌روزرسانی‌های وضعیت اضافه می‌کند.

برای گنجاندن این ماژول، موارد زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

شیک

dependencies {
    implementation "com.google.android.play:core-ktx:1.8.1"
}

کاتلین

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 استفاده کنید.