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
API
بتطبيق التغييرات بشكلٍ موحّد.
في ما يلي مثال على إحدى وظائف Android KTX Core، وهي دالة
SharedPreferences.edit
،
التي تضيف دالة تعديل إلى SharedPreferences
. تستخدِم هذه الدالة علامة boolean
اختيارية كوسيطة أولى تشير إلى ما إذا كان سيتم تأكيد
التغييرات أو تطبيقها. ويتلقّى أيضًا إجراءً لتنفيذه على محرِّر
SharedPreferences
في شكل دالة lambda.
// 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() }
Kotlin
repositories { google() }
وحدات AndroidX
يتم تنظيم Android KTX في وحدات تحتوي كلّ منها على حِزمة واحدة أو أكثر.
يجب تضمين عنصر ربط لكل عنصر في الوحدة في ملف
build.gradle
الخاص بالتطبيق. تذكَّر إلحاق رقم الإصدار بالعنصر.
يمكنك العثور على أرقام أحدث إصدار في القسم المقابل لكل عنصر أثري
في هذا الموضوع.
يحتوي Android KTX على وحدة أساسية واحدة توفّر امتدادات Kotlin لواجهات برمجة التطبيقات الشائعة للإطارات الأساسية والعديد من الإضافات الخاصة بالنطاق.
باستثناء الوحدة الأساسية، تستبدل جميع عناصر وحدة KTX
التبعية الأساسية لـ Java في ملف build.gradle
. على سبيل المثال، يمكنك
استبدال تبعية 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.13.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.13.1") }
في ما يلي قائمة بالحِزم المضمّنة في وحدة 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
مجموعة KTX
تحتوي إضافات "المجموعات" على وظائف مساعدة للعمل مع مكتبات المجموعات التي تُوفّر استهلاكًا منخفضًا للذاكرة في Android، بما في ذلك ArrayMap
وLongSparseArray
LruCache
وغيرها.
لاستخدام هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
رائع
dependencies { implementation "androidx.collection:collection-ktx:1.4.5" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.5") }
تستفيد إضافات المجموعات من تحميل عامل التشغيل الزائد في 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
في تطبيقك:
Groovy
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.3" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.3") }
باستخدام وحدة Fragment KTX، يمكنك تبسيط معاملات الأجزاء باستخدام لامدا، على سبيل المثال:
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
تحدِّد حزمة KTX لدورة الحياة LifecycleScope
لكل عنصر
Lifecycle
. يتم إلغاء أي دالة معالجة متزامنة
تم تشغيلها في هذا النطاق عند إتلاف Lifecycle
. يمكنك
الوصول إلى CoroutineScope
من Lifecycle
باستخدام السمتَين
lifecycle.coroutineScope
أو lifecycleOwner.lifecycleScope
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
رائع
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") }
يوضّح المثال التالي كيفية استخدام 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
لإنشاء liveData
تُشغِّل دالة suspend
وتعرض النتيجة كعنصر LiveData
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
رائع
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7") }
في المثال التالي، loadUser()
هي دالة تعليق تمّ الإعلان عنها في مكان آخر.
يمكنك استخدام دالة الإنشاء liveData
لاستدعاء loadUser()
بشكل غير متزامن،
ثم استخدام emit()
لعرض النتيجة:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
لمزيد من المعلومات حول استخدام الكوروتينات مع LiveData
، يمكنك الاطّلاع على مقالة
استخدام الكوروتينات في لغة Kotlin مع مكوّنات بنية التطبيق.
Navigation KTX
يحتوي كل مكوّن من مكوّنات مكتبة Navigation على إصدار KTX خاص به يُعدّل واجهة برمجة التطبيقات لتكون أكثر إيجازًا وأكثر توافقًا مع لغة Kotlin.
لتضمين هذه الوحدات، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.8.1" implementation "androidx.navigation:navigation-fragment-ktx:2.8.1" implementation "androidx.navigation:navigation-ui-ktx:2.8.1" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.8.1") implementation("androidx.navigation:navigation-fragment-ktx:2.8.1") implementation("androidx.navigation:navigation-ui-ktx:2.8.1") }
استخدِم دوالّ الإضافات وتفويض الموقع للوصول إلى وسيطات الوجهة والتنقّل إلى الوجهات، كما هو موضّح في المثال التالي:
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
في تطبيقك:
Groovy
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
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.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7") }
على سبيل المثال، نفترض أنّ قاعدة بيانات تتضمّن قائمة صغيرة من المستخدمين. في تطبيقك، يتم تحميل قاعدة البيانات في الذاكرة ثم عرض بيانات المستخدمين في واجهة المستخدم. لتحقيق
هذا، يمكنك استخدام 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)
}
غرفة KTX
توفّر إضافات الغرف إمكانية استخدام وحدات معالجة المهام المتزامنة لمعاملات قاعدة البيانات.
لاستخدام هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
Groovy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
في ما يلي بعض الأمثلة التي تستخدم فيها 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
في تطبيقك:
Groovy
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.4.0" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.4.0") }
في ما يلي مثال على استخدام إضافة transaction
لإجراء معاملة في قاعدة بيانات:
db.transaction {
// insert data
}
ViewModel KTX
توفّر مكتبة ViewModel KTX دالة viewModelScope()
تسهِّل
بدء عمليات التشغيل المتعدّد للوظائف من ViewModel
. يتم ربط
CoroutineScope
بـ Dispatchers.Main
ويتم إلغاؤه تلقائيًا
عند محو ViewModel
. يمكنك استخدام viewModelScope()
بدلاً من
إنشاء نطاق جديد لكل ViewModel
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5") }
على سبيل المثال، تبدأ الدالة 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
في تطبيقك:
Groovy
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.1") }
بدلاً من توسيع نطاق 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
لتعليق دالة coroutine الحالية.
في ما يلي مثال على تعليق القيمة
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
تحتوي بعض حِزم تطوير البرامج (SDK) لمنصّة Firebase لنظام التشغيل Android على مكتبات إضافية لتنسيق Kotlin تتيح لك كتابة رمز Kotlin مألوف عند استخدام Firebase في تطبيقك. لمزيد من المعلومات، اطّلِع على المواضيع التالية:
Google Maps Platform KTX
تتوفّر إضافات KTX لحِزم تطوير البرامج (SDK) لنظام التشغيل Android من Google Maps Platform، والتي تسمح لك بالاستفادة من العديد من ميزات لغة Kotlin، مثل الدوالّ الموسّعة والمَعلمات المُسمّاة والمَعلمات التلقائية وإعلانات إزالة البنية والعمليات المتكرّرة. لمزيد من المعلومات، اطّلِع على المواضيع التالية:
حزمة KTX لـ Play Core
تضيف حزمة KTX في Play Core إمكانية استخدام وظائف Kotlin المتكررة للطلبات التي يتم تنفيذها لمرة واحدة ووظائف Flow
لرصد آخر المعلومات المتعلّقة بالحالة من خلال إضافة وظائف إضافية إلى SplitInstallManager
وAppUpdateManager
في مكتبة Play Core.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف 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.