مقدمة عن التدفقات

يستخدم إصدار Kotlin من واجهات برمجة التطبيقات Home APIs عمليات تدفق البيانات، وهي ميزة في لغة Kotlin توفّر إمكانات قوية لمعالجة مصادر البيانات غير المتزامنة، بما في ذلك التحويل والفلترة ووضع الخرائط والتحويل إلى المجموعات والعكس، وما إلى ذلك.

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

يستردّ المستهلك البيانات من إحدى عمليات المعالجة في عملية تُعرف باسم الجمع. تحتوي عمليات Kotlin على دالة collect() يمكن استخدامها لهذا الغرض. يعتمد ما يحدث في عملية التنقّل أثناء عملية الجمع على نوع عملية التنقّل.

تكون عمليات تدفق Kotlin (Flow<T>) غير نشِطة تلقائيًا، ما يعني أنّ رمز باني عملية التدفق لا يُنشئ بيانات إلا عند استدعاء collect(). في المقابل، يُنشئ تدفق البيانات الحية البيانات على الفور، ويخزّنها في الذاكرة مثل قائمة انتظار لاستخدامها متى شئت. ولأنّه يحافظ على البيانات في الذاكرة، يُعتبر تدفق البيانات الرائج مرتبطًا بالحالة.

يمكن تحويل مسارات الإحالات الناجحة من مسار إحالة ناجحة غير رائج إلى مسار إحالة ناجحة رائج باستخدام عامل التشغيل shareIn (راجِع تحويل مسارات الإحالات الناجحة غير الرائجة إلى رائجة باستخدام shareIn ). يمكنك أيضًا استخدام SharedFlow أو StateFlow لتحويل مسار إحالة ناجحة غير رائج إلى مسار إحالة ناجحة رائج.

كيفية استخدام التطبيق النموذجي للعمليات

يستخدم نموذج التطبيق نماذج العرض في Jetpack Compose المرتبطة بالعمليات في Home APIs. تعتمد العديد من نماذج عناصر واجهة المستخدم في التطبيق على الحالة، ولكن يمكن التفاعل معها. يمزج نموذج التطبيق أيضًا حالة الأجهزة مع حالة "متفائلة" في واجهة المستخدم لتوفير تجربة مستخدم في الوقت الفعلي. تعني عبارة "التوقعات المتفائلة" أنّه يفترِض التطبيق نجاح إجراء معيّن ويُعدِّل واجهة المستخدم على الفور لعكس النتيجة المتوقّعة بدون انتظار تأكيد. إذا تبيّن أنّه تعذّر تنفيذ الإجراء، يتم تعديل واجهة المستخدم لتعكس الحالة الفعلية.

في نموذج التطبيق، يتم إنشاء مسارات لكل طبقة من نموذج العرض (التصاميم، والغرف، والأجهزة). على سبيل المثال، يتم إجراء ذلك للبنى التي تحتوي على العبارة التالية في GlobalViewModel.kt:

  fun getStructuresState(): StateFlow<List<StructureModel>?> =
    homeClient
      .structures()
      .map { structures -> structures.map { StructureModel(it.name, it) }.sortedBy { it.name } }
      .handleErrors()
      .flowOn(Dispatchers.IO)
      .stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), null)

يجمع emitAll() جميع القيم من عملية معالجة معيّنة ويرسلها إلى المجمّع. تشارك stateIn() القيمة التي تمّ إصدارها مؤخرًا من مثيل واحد قيد التشغيل من عملية البثّ إلى الأعلى مع عدة مشتركين في عملية البثّ إلى الأسفل. يُرجى الاطّلاع على مرجع kotlinx.coroutines.flow لمزيد من المعلومات.

Jetpack Compose

لتخزين عناصر التدفق في الذاكرة المحلية ومنعها من الإغلاق، استخدِم واجهة برمجة التطبيقات Kotlin remember.

في Jetpack Compose، إذا كنت تستخدم هذا الإجراء مع collectAsStateWithLifecycle()، تدير Jetpack تلقائيًا الاشتراك في عمليات التدفق وإلغاء الاشتراك فيها استنادًا إلى ما إذا كان واجهة مستخدم التطبيق التي تعرض هذه الحالة ظاهرة في المقدّمة أم لا.

ويمكنك إجراء ذلك من خلال طلب بسيط في نموذج التطبيق. باستخدام الدالة getStructuresState() الموضَّحة سابقًا:

val structuresList by
    remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()

الآن، عند تغيير أي حالة للبنية (مثل name)، ستعكس دالة Composable التي تستخدمها هذه الحالة المعدَّلة تلقائيًا. في نموذج التطبيق، هذه هي الدالة HomeActivityContent().

الموارد

لمزيد من المعلومات حول Kotlin وعمليات تدفق البيانات وعمليات التشغيل المتعدّد وJetpack Compose، يُرجى الاطّلاع على الموارد التالية: