Android KTX جزء من Android Jetpack.
حزمة Android KTX هي مجموعة من إضافات Kotlin المضمّنة في Jetpack لنظام التشغيل Android ومكتبات Android الأخرى. توفّر إضافات KTX لغة Kotlin مختصرة وواضحة لاستخدامها مع Jetpack ونظام Android الأساسي وواجهات برمجة التطبيقات الأخرى. ولإجراء ذلك، تستفيد هذه الإضافات من العديد من ميزات لغة Kotlin، بما في ذلك ما يلي:
- دوال الإضافات
- سمات الإضافة
- الدوالّ اللامدا
- المَعلمات المُعنوَنة
- القيم التلقائية للمَعلمة
- الكوروتينات
على سبيل المثال، عند استخدام
SharedPreferences
، يجب
إنشاء محرِّر
قبل إجراء تعديلات على بيانات الإعدادات المفضّلة. يجب عليك أيضًا تطبيق هذه التغييرات أو تطبيقها عند الانتهاء من التعديل، كما هو موضح في المثال التالي:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
وتتناسب لغة Kotlin lambdas بشكل مثالي مع حالة الاستخدام هذه. تتيح لك هذه الأدوات اتّباع أسلوبٍ
أكثر إيجازًا من خلال تمرير مجموعة من الرموز البرمجية لتنفيذها بعد
إنشاء المحرِّر، والسماح بتنفيذ الرمز البرمجي، ثم السماح لواجهة 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
عند كل
مرة يتم فيها استدعاء هذه الدالة.
إنّ نمط تمرير الرموز البرمجية باستخدام دالة lambdas وتطبيق الإعدادات التلقائية المعقولة التي يمكن
تجاوزها وإضافة هذه السلوكيات إلى واجهات برمجة التطبيقات الحالية باستخدام وظائف إضافة inline
هو نمط نموذجي للتحسينات التي توفّرها مكتبة KTX في Android.
استخدام أداة Android KTX في مشروعك
لبدء استخدام Android KTX، أضِف التبعية التالية إلى ملف
build.gradle
في مشروعك:
وحدات AndroidX
يتم تنظيم Android KTX في وحدات، حيث تحتوي كل وحدة على حزمة واحدة أو أكثر.
يجب تضمين عنصر ربط لكل عنصر في الوحدة في ملف
build.gradle
الخاص بالتطبيق. تذكَّر إلحاق رقم الإصدار بالعنصر.
يمكنك العثور على أرقام أحدث إصدار في القسم المقابل لكل عنصر أثري
في هذا الموضوع.
يحتوي Android KTX على وحدة أساسية واحدة توفّر امتدادات Kotlin لواجهات برمجة التطبيقات الشائعة للإطارات الأساسية والعديد من الإضافات الخاصة بالنطاق.
باستثناء الوحدة الأساسية، تستبدل جميع عناصر وحدة KTX
التبعية الأساسية لـ Java في ملف build.gradle
. على سبيل المثال، يمكنك
استبدال تبعية androidx.fragment:fragment
بأحد تبعيات
androidx.fragment:fragment-ktx
. تساعد هذه البنية في إدارة
الإصدارات بشكل أفضل ولا تضيف متطلبات إضافية لبيان التبعية.
حزمة KTX الأساسية
توفّر وحدة Core KTX إضافات للمكتبات الشائعة التي تشكل جزءًا من إطار عمل Android. لا تحتوي هذه المكتبات على تبعيات مستندة إلى Java
عليك إضافتها إلى build.gradle
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
dependencies { implementation "androidx.core:core-ktx:1.15.0" }
dependencies { implementation("androidx.core:core-ktx:1.15.0") }
في ما يلي قائمة بالحِزم المضمّنة في وحدة 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" }
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
جزء من KTX
توفّر وحدة Fragment KTX عددًا من الإضافات لتبسيط واجهة برمجة التطبيقات Fragment API.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
dependencies {
implementation "androidx.fragment:fragment-ktx:1.8.3"
}
dependencies {
implementation("androidx.fragment:fragment-ktx:1.8.3")
}
باستخدام وحدة Fragment KTX، يمكنك تبسيط معاملات التجزئة باستخدام دالة lambda، على سبيل المثال:
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>()
دورة حياة KTX
تحدِّد حزمة KTX لدورة الحياة LifecycleScope
لكل عنصر
Lifecycle
. يتم إلغاء أي دالة معالجة متزامنة
تم تشغيلها في هذا النطاق عند إتلاف Lifecycle
. يمكنك
الوصول إلى CoroutineScope
من Lifecycle
باستخدام السمتَين
lifecycle.coroutineScope
أو lifecycleOwner.lifecycleScope
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
dependencies {
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.7"
}
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"
}
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 مع مكوّنات بنية التطبيق.
لوحة التنقل KTX
يحتوي كل مكوّن من مكوّنات مكتبة Navigation على إصدار KTX خاص به يُعدّل واجهة برمجة التطبيقات لتكون أكثر إيجازًا وأكثر توافقًا مع لغة Kotlin.
لتضمين هذه الوحدات، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.8.8" implementation "androidx.navigation:navigation-fragment-ktx:2.8.8" implementation "androidx.navigation:navigation-ui-ktx:2.8.8" }
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.8.8") implementation("androidx.navigation:navigation-fragment-ktx:2.8.8") implementation("androidx.navigation:navigation-ui-ktx:2.8.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)
}
}
...
}
لوحة ألوان 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]
فيديوهات KTX التفاعلية
تتيح لك وحدة Reactive Streams KTX إنشاء بث LiveData
قابل للرصد من
ناشر ReactiveStreams
.
لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle
في تطبيقك:
dependencies {
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7"
}
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
في تطبيقك:
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
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
في تطبيقك:
dependencies {
implementation "androidx.sqlite:sqlite-ktx:2.4.0"
}
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
في تطبيقك:
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5"
}
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
في تطبيقك:
dependencies {
implementation "androidx.work:work-runtime-ktx:2.9.1"
}
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" والتي تتيح لك الاستفادة من العديد من ميزات لغة 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" }
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.