Android KTX جزء من Android Jetpack.

إنّ Android KTX هو مجموعة من إضافات Kotlin التي يتم تضمينها في نظام التشغيل Android Jetpack ومكتبات Android الأخرى. توفّر إضافات KTX لتنفيذ ذلك، تستفيد هذه الإضافات من العديد من ميزات لغة Kotlin، بما في ذلك ما يلي:

  • دوال الإضافات
  • خصائص الإضافة
  • لامداس
  • المَعلمات المُسمّاة
  • القيم التلقائية للمعلَمات
  • الكوروتين

على سبيل المثال، عند استخدام SharedPreferences، عليك إنشاء محرِّر قبل أن تتمكّن من إجراء تعديلات على بيانات الإعدادات المفضّلة. يجب أيضًا تطبيق هذه التغييرات أو تنفيذها عند الانتهاء من التعديل، كما هو موضّح في المثال التالي:

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

تُعد Kotlin lambdas مناسبة تمامًا لحالة الاستخدام هذه. وهي تتيح لك اتّباع نهج أكثر إيجازًا من خلال تمرير مجموعة من الرموز البرمجية لتنفيذها بعد إنشاء أداة التعديل، والسماح بتنفيذ الرمز، ثم السماح لواجهة برمجة تطبيقات SharedPreferences بتطبيق التغييرات بشكل شامل.

في ما يلي مثال على إحدى وظائف 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 في كل مرة يتم فيها استدعاء هذه الدالة.

وهذا النمط من تمرير الرموز باستخدام ملفات lambda، وتطبيق إعدادات تلقائية معقولة يمكن تجاوزها، وإضافة هذه السلوكيات إلى واجهات برمجة التطبيقات الحالية باستخدام دوال الإضافات inline هي أسلوب نموذجي للتحسينات التي تقدمها مكتبة KTX في نظام التشغيل Android.

استخدام 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. يساعد بناء الجملة هذا في إدارة الإصدارات بشكل أفضل ولا يضيف متطلبات بيان تبعية إضافية.

مجموعة KTX الأساسية

توفّر وحدة Core KTX امتدادات للمكتبات الشائعة التي تشكّل جزءًا من إطار عمل Android. لا تتضمّن هذه المكتبات تبعيات مستندة إلى لغة Java وعليك إضافتها إلى build.gradle.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

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

فيما يلي قائمة بالحزم الموجودة في وحدة Core KTX:

مجموعة KTX

تحتوي إضافات المجموعة على وظائف مفيدة للعمل مع مكتبات المجموعات الفعالة في الذاكرة على Android، بما في ذلك ArrayMap وLongSparseArray وLruCache وغيرها.

لاستخدام هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

dependencies {
    implementation("androidx.collection:collection-ktx:1.3.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

جزء KTX

توفِّر وحدة KTX Fragment عددًا من الإضافات لتبسيط واجهة برمجة التطبيقات للأجزاء.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

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

باستخدام وحدة 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.6.2"
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
}

يوضح المثال التالي كيفية استخدام 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)
        }
    }
}

تنسيق KTX لبيانات LiveData

عند استخدام LiveData، قد تحتاج إلى حساب القيم بشكل غير متزامن. على سبيل المثال، قد ترغب في استرداد تفضيلات المستخدم وعرضها على واجهة المستخدم. بالنسبة إلى هذه الحالات، توفر LiveData KTX دالة إنشاء liveData تستدعي الدالة suspend وتعرض النتيجة ككائن LiveData.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
}

في المثال التالي، loadUser() هي دالة تعليق تم تعريفها في مكان آخر. يمكنك استخدام دالة إنشاء liveData لطلب loadUser() بشكل غير متزامن، ثم استخدام emit() لإرسال النتيجة:

val user: LiveData<User> = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
}

لمزيد من المعلومات عن استخدام الكوروتينات مع LiveData، يُرجى الاطّلاع على المقالة استخدام الكوروتينات في لغة Kotlin مع مكوّنات البنية.

يحتوي كل مكون من مكونات مكتبة التنقل على إصدار KTX الخاص به الذي يكيف واجهة برمجة التطبيقات لتكون أكثر إيجازًا واصطلاحية بلغة Kotlin.

لتضمين هذه الوحدات، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

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

استخدِم دوال الإضافات وتفويض الموقع للوصول إلى وسيطات الوجهة والانتقال إلى الوجهات، كما هو موضّح في المثال التالي:

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"
}

Kotlin

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

على سبيل المثال، عند العمل مع مثيل Palette، يمكنك استرداد نموذج selected لـ target معيّن باستخدام عامل التشغيل get ([ ]):

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

فيديوهات بث مباشر KTX

تتيح لك وحدة KTX لساحات المشاركات التفاعلية إنشاء بث LiveData يمكن ملاحظته من ناشر ReactiveStreams.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

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

كمثال، لنفترض أن قاعدة البيانات بها قائمة صغيرة من المستخدمين. في تطبيقك، يمكنك تحميل قاعدة البيانات في الذاكرة ثم عرض بيانات المستخدم في واجهة المستخدم. لتحقيق ذلك، يمكنك استخدام 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

تضيف إضافات الغرف دعمًا كوروتيني لمعاملات قاعدة البيانات.

لاستخدام هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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 لتطبيقك:

رائع

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

Kotlin

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

في ما يلي مثال على استخدام الإضافة transaction لإجراء معاملة في قاعدة البيانات:

db.transaction {
    // insert data
}

عرض الطراز KTX

توفّر مكتبة ViewModel KTX دالة viewModelScope() التي تسهّل تشغيل coroutines من ViewModel. يتم ربط CoroutineScope بـ Dispatchers.Main ويتم إلغاؤه تلقائيًا عند محو ViewModel. يمكنك استخدام viewModelScope() بدلاً من إنشاء نطاق جديد لكل ViewModel.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف build.gradle لتطبيقك:

رائع

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

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
}

على سبيل المثال، تُشغِّل دالة 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.0"
}

Kotlin

dependencies {
    implementation("androidx.work:work-runtime-ktx:2.9.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، راجِع Threading في 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.

لوحة KTX لمنصة Firebase

تحتوي بعض حزم SDK لمنصة Firebase لنظام التشغيل Android على مكتبات إضافات Kotlin التي تتيح لك كتابة رمز Kotlin الاصطلاحي عند استخدام Firebase في تطبيقك. ولمزيد من المعلومات، يُرجى الاطّلاع على المواضيع التالية:

منصة خرائط Google KTX

تتوفّر إضافات KTX لحِزم تطوير البرامج (SDK) لنظام التشغيل Android في "منصة خرائط Google" تتيح لك الاستفادة من العديد من ميزات لغة Kotlin مثل دوال الإضافات والمَعلمات المُسمّاة والوسيطات التلقائية والتعريفات الإتلافية والكوروتينات. لمزيد من المعلومات، يمكنك الاطّلاع على المواضيع التالية:

تشغيل Core KTX

يضيف Play Core KTX إلى الكوروتينات في لغة Kotlin لطلبات اللقطة الواحدة وعملية مراقبة تحديثات الحالة من خلال إضافة وظائف الإضافات إلى SplitInstallManager وAppUpdateManager في مكتبة Play الأساسية.

لتضمين هذه الوحدة، أضِف ما يلي إلى ملف 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.