تحديد طلبات العمل

يتناول دليل البدء كيفية إنشاء WorkRequest بسيط. وإدراجه في قائمة الانتظار.

ستتعرَّف في هذا الدليل على كيفية تحديد عناصر WorkRequest وتخصيصها. للتعامل مع حالات الاستخدام الشائعة، مثل كيفية:

  • جدولة العمل لمرة واحدة والعمل المتكرر
  • وضع قيود على العمل، مثل طلب شبكة Wi-Fi أو الشحن
  • ضمان الحد الأدنى من التأخير في تنفيذ العمل
  • وضع استراتيجيتَي إعادة المحاولة والتراجع
  • تمرير بيانات الإدخال إلى العمل
  • تجميع الأعمال ذات الصلة معًا باستخدام العلامات

نظرة عامة

ويتم تحديد العمل في WorkManager عبر WorkRequest. من أجل جدولة أي عمل باستخدام WorkManager، فيجب أولاً إنشاء WorkRequest ثم إدراجه في قائمة الانتظار.

Kotlin

val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

Java

WorkRequest myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest);

يحتوي كائن WorkRequest على جميع المعلومات التي يحتاجها WorkManager جدولة عملك وتشغيله. وهو يتضمن القيود التي يجب الوفاء بها من أجل وعمل على تشغيله، وجدولة معلومات مثل التأخيرات أو الفواصل الزمنية المتكررة، وإعادة المحاولة وقد يتضمن بيانات إدخال إذا كان عملك يعتمد عليها.

WorkRequest نفسها هي فئة أساسية مجردة. هناك خياران عمليات التنفيذ المستمدة من هذه الفئة والتي يمكنك استخدامها لإنشاء الطلب، "OneTimeWorkRequest" وPeriodicWorkRequest" كما تشير أسماؤها، إنّ "OneTimeWorkRequest" مفيد في جدولة المواعيد. عمل غير متكرر، في حين أن PeriodicWorkRequest أكثر ملاءمة جدولة عمل يتكرر على فترات زمنية معينة.

تحديد موعد للعمل لمرة واحدة

بالنسبة إلى العمل البسيط، الذي لا يتطلب تهيئة إضافية، استخدم واجهة برمجة التطبيقات الثابتة الطريقة from:

Kotlin

val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

Java

WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);

بالنسبة للعمل الأكثر تعقيدًا، يمكنك استخدام إحدى أدوات الإنشاء:

Kotlin

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

Java

WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

جدولة العمل المستعجل

قدم WorkManager 2.7.0 مفهوم العمل الإسراع. هذا يسمح WorkManager لتنفيذ عمل مهم مع منح النظام تحكمًا أفضل في الوقت نفسه على الوصول إلى الموارد.

يتميز العمل المستعجل بالخصائص التالية:

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

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

الحصص

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

يعتمد مقدار وقت التنفيذ المتاح للتطبيق على حزمة الاستعداد وأهمية العملية.

يمكنك تحديد ما يحدث عندما لا تسمح حصة التنفيذ مهمة عاجلة لتشغيلها على الفور. يمكنك الاطّلاع على المقتطفات أدناه لمعرفة التفاصيل.

تنفيذ العمل الإسراع

بدءًا من الإصدار 2.7 من WorkManager، يمكن لتطبيقك الاتصال بـ setExpedited() للإشارة إلى أنّ يجب تشغيل WorkRequest في أسرع وقت ممكن باستخدام مهمة مستعجلة. تشير رسالة الأشكال البيانية في ما يلي مقتطف الرمز مثالاً على كيفية استخدام setExpedited():

Kotlin

val request = OneTimeWorkRequestBuilder<SyncWorker>()
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build()

WorkManager.getInstance(context)
    .enqueue(request)

Java

OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
    .setInputData(inputData)
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build();

في هذا المثال، نبدأ بمثيل OneTimeWorkRequest ونستدعي setExpedited() عليه. وعندئذٍ، يصبح هذا الطلب تسريعًا للعملية. إذا كانت الحصة سيبدأ تشغيله على الفور في الخلفية. إذا كانت الحصة مستخدمة، تشير معلمة OutOfQuotaPolicy إلى أنه ينبغي كعمل عادي غير سريع.

التوافق مع الأنظمة القديمة والخدمات التي تعمل في المقدّمة

للحفاظ على التوافق مع الأنظمة القديمة للمهام التي يتم تسريعها، قد يشغِّل تطبيق WorkManager خدمة تعمل في المقدّمة على إصدارات النظام الأساسي الأقدم من 12. يمكن للخدمات التي تعمل في المقدّمة عرض إشعار للمستخدم.

الطريقتان getForegroundInfoAsync() وgetForegroundInfo() في العامل تفعيل WorkManager لعرض إشعار عند الاتصال بـ setExpedited() التي تسبق Android 12.

على أي ListenableWorker تنفيذ طريقة getForegroundInfo في حال: أن تطلب أن تعمل المهمة كمهمة مستعجلة.

عند استهداف الإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث، ستظل الخدمات التي تعمل في المقدّمة متاحة باستخدام طريقة setForeground المقابلة.

عامل

ولا يعرف العاملون ما إذا كان العمل الذي يؤدونه تم تسريعه أم لا. لَكِنْ يمكن للعاملين عرض إشعار في بعض إصدارات Android عند تم تسريع عملية البحث عن "WorkRequest".

لتفعيل ذلك، يوفّر WorkManager الطريقة getForegroundInfoAsync()، والذي يجب تنفيذه حتى يتمكن WorkManager من عرض إشعار لبدء ForegroundService لك عند الضرورة.

عامل الكوروتين

في حال استخدام CoroutineWorker، يجب تنفيذ getForegroundInfo(). يمكنك حينئذٍ إرساله إلى setForeground() خلال doWork() سيؤدي القيام بذلك إلى إنشاء في إصدارات Android الأقدم من 12.

ضع في الاعتبار المثال التالي:

  class ExpeditedWorker(appContext: Context, workerParams: WorkerParameters):
   CoroutineWorker(appContext, workerParams) {

   override suspend fun getForegroundInfo(): ForegroundInfo {
       return ForegroundInfo(
           NOTIFICATION_ID, createNotification()
       )
   }

   override suspend fun doWork(): Result {
       TODO()
   }

    private fun createNotification() : Notification {
       TODO()
    }

}

سياسات الحصص

يمكنك التحكّم في ما يحدث لتسريع العمل عندما يصل التطبيق إلى حصة التنفيذ. للمتابعة، يمكنك تمرير setExpedited():

  • OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST، مما يتسبب في كطلب عمل عادي. يوضح المقتطف أعلاه هذا.
  • OutOfQuotaPolicy.DROP_WORK_REQUEST، يؤدي ذلك إلى إلغاء الطلب في حال لا توجد حصة كافية.

نموذج تطبيق

للاطلاع على مثال كامل لكيفية استخدام WorkManager 2.7.0 للعمل الإسراع، انظر من خلال WorkManagerSample على GitHub.

تأجيل العمل المستعجل

ويحاول النظام تنفيذ مهمة معينة عاجلة في أقرب وقت ممكن بعد استدعاء الوظيفة. ومع ذلك، وكما هو الحال مع الأنواع الأخرى من الوظائف، يستطيع النظام قد تؤجل بدء العمل الجديد المُعجَّل، كما هو الحال في الحالات التالية:

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

جدولة العمل الدوري

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

في ما يلي كيفية استخدام PeriodicWorkRequest لإنشاء كائن WorkRequest ينفذ بشكل دوري:

Kotlin

val saveRequest =
       PeriodicWorkRequestBuilderS<aveImageToFileWorker(>1, TimeUnit.HOURS)
    // Additional configuration
           .build()

Java

PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

في هذا المثال، تتم جدولة العمل بفاصل ساعة واحدة.

ويتم تحديد الفترة الزمنية على أنّها أدنى مدة فاصلة بين مرات التكرار. تشير رسالة الأشكال البيانية يعتمد الوقت الدقيق الذي سيتم فيه تنفيذ العامل على القيود الذي تستخدمه في كائن WorkRequest وفي التحسينات التي تم إجراؤها النظام.

فواصل زمنية مرنة للتشغيل

إذا كانت طبيعة عملك تجعل توقيت التشغيل حساسًا، يمكنك ضبط يجب تنفيذ "PeriodicWorkRequest" ضمن مرونة نقطة داخل كل فترة فاصلة، كما هو موضح في الشكل 1.

يمكنك ضبط فاصل زمني مرن لمهمة دورية. أنت تحدد فاصل تكرار،
وفاصل زمني مرن يحدد مقدارًا معينًا من الوقت في نهاية
تكرار الفاصل الزمني. يحاول WorkManager تشغيل وظيفتك في مرحلة ما خلال
الفاصل المرن في كل دورة.

الشكل 1. رسم بياني يوضح الفواصل الزمنية المتكررة مع النقطة المرنة التي يمكن للعمل فيها.

لتحديد العمل الدوري باستخدام نقطة مرنة، عليك تمرير flexInterval مع repeatInterval عند إنشاء PeriodicWorkRequest. فترة المرونة يبدأ في repeatInterval - flexInterval، ويصل إلى نهاية الفاصل.

في ما يلي مثال على الأعمال الدورية التي يمكن تنفيذها خلال آخر 15 يومًا. دقيقة من كل فترة ساعة.

Kotlin

val myUploadWork = PeriodicWorkRequestBuilderS<aveImageToFileWorker(>
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

Java

WorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

يجب أن يكون الفاصل الزمني للتكرار أكبر من أو يساوي "PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS" والمرونة المرنة يجب أن تكون الفاصل الزمني أكبر من أو يساوي PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS

تأثير القيود على العمل الدوري

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

قيود العمل

تضمن القيود تأجيل العمل حتى يتم استيفاء الشروط المثلى. تتوفر القيود التالية لـ WorkManager.

NetworkType تقيد نوع الشبكة المطلوبة لتشغيل عملك. على سبيل المثال، شبكة Wi-Fi (UNMETERED).
البطارية غير منخفضة وعند ضبط هذه السياسة على "صحيح"، لن يتم تنفيذ العمل إذا كان الجهاز في وضع البطارية المنخفضة.
يتطلب شحن عند ضبط هذه السياسة على "صحيح"، لن يتم تنفيذ عملك إلا أثناء شحن الجهاز.
DeviceIdle عند ضبط هذه السياسة على "صحيح"، يتطلب ذلك أن يكون جهاز المستخدم غير نشِط لفترة قصيرة قبل بدء العمل. ويمكن أن يكون ذلك مفيدًا لتنفيذ العمليات المجمَّعة التي قد يكون لها تأثير سلبي في أداء التطبيقات الأخرى التي تعمل بشكلٍ نشط على جهاز المستخدم.
مساحة التخزين غير منخفضة عند ضبط هذه السياسة على "صحيح"، لن يتم تنفيذ عملك إذا كانت مساحة التخزين للمستخدم على الجهاز منخفضة جدًا.

لإنشاء مجموعة من القيود وربطها ببعض الأعمال، قم بإنشاء يستخدم المثيل Constraints المثيل Contraints.Builder() ويعيّنه إلى WorkRequest.Builder()

على سبيل المثال، تُنشئ التعليمة البرمجية التالية طلب عمل لا يتم تشغيله إلا عندما شحن جهاز المستخدِم وشبكة Wi-Fi:

Kotlin

val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilderM<yWork(>)
       .setConstraints(constraints)
       .build()

Java

Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setConstraints(constraints)
               .build();

عند تحديد قيود متعددة، لن يتم تشغيل عملك إلا عندما يتم تلبية القيود.

في حالة عدم تلبية أحد القيود أثناء تشغيل عملك، سيوقف WorkManager العامل لديك. وستتم إعادة محاولة العمل بعد ذلك تلبية القيود.

تأخير العمل

في حال عدم وجود قيود على عملك أو إذا كانت جميع القيود عند إدراج عملك في قائمة الانتظار، فقد يختار النظام تشغيل العمل فورًا. إذا لم تكن ترغب في تشغيل العمل على الفور، يمكنك تحديد عملك للبدء بعد الحد الأدنى من التأخير الأوّلي.

في ما يلي مثال على كيفية ضبط عملك ليتم تنفيذه بعد 10 دقائق على الأقل منه إضافته إلى قائمة الانتظار.

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

Java

WorkRequest myWorkRequest =
      new OneTimeWorkRequest.Builder(MyWork.class)
               .setInitialDelay(10, TimeUnit.MINUTES)
               .build();

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

سياسة إعادة المحاولة والتراجع

إذا كنت تريد أن يعيد WorkManager تنفيذ عملك، يمكنك الرجوع Result.retry() من العامل الخاص بك. يكون عملك عندئذٍ وتتم إعادة جدولته وفقًا لتأخيرات التراجع وسياسة التراجع.

  • يحدِّد تأخُّر الاستعداد الحد الأدنى لمدة الانتظار قبل إعادة المحاولة. عملك بعد المحاولة الأولى. لا يمكن أن تكون هذه القيمة أقل من 10 ثوانٍ. (أو MIN_BACKOFF_MILLIS).

  • تحدد سياسة التراجع كيفية زيادة تأخير التراجع بمرور الوقت محاولات إعادة المحاولة اللاحقة. يدعم WorkManager سياستي التراجع، LINEAR و EXPONENTIAL

يشمل كل طلب عمل سياسة تراجع وتأخير في التراجع. السياسة التلقائية EXPONENTIAL مع تأخير مدّته 30 ثانية، ولكن يمكنك إلغاء ذلك في تهيئة طلب العمل.

في ما يلي مثال على تخصيص السياسة والتأخير في التراجع.

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()

Java

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setBackoffCriteria(
                       BackoffPolicy.LINEAR,
                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                       TimeUnit.MILLISECONDS)
               .build();

في هذا المثال، يتم تعيين الحد الأدنى لتأخير التراجع على القيمة الأدنى المسموح بها، 10 ثوانٍ بما أنّ السياسة LINEAR، سيزيد الفاصل الزمني لإعادة المحاولة بمقدار حوالي 10 ثوانٍ مع كل محاولة جديدة. على سبيل المثال، يمكن أن يجري تشغيل أول ستتم إعادة محاولة الانتهاء باستخدام Result.retry() بعد 10 ثوانٍ، تليها 20 و30 و40 وهكذا، إذا استمر العمل في العودة Result.retry() بعد المحاولات اللاحقة. إذا تم ضبط سياسة التراجع على EXPONENTIAL، سيكون تسلسل مدة إعادة المحاولة أقرب إلى 20 و40 و80 وهكذا. مفعَّلة.

وضع العلامات

لكل طلب عمل معرّف فريد يمكن استخدامه لتحديد تعمل لاحقًا من أجل إلغاء العمل أو ملاحظة تقدمه.

إذا كانت لديك مجموعة من الأعمال ذات الصلة منطقيًا، فقد تجد أنه من المفيد أيضًا وضع علامة على بنود العمل هذه. من خلال وضع العلامات، يمكنك العمل مع مجموعة من مهام العمل الطلبات معًا.

على سبيل المثال، يؤدي WorkManager.cancelAllWorkByTag(String) إلى الإلغاء. جميع طلبات العمل بعلامة معينة، تعرض الدالة WorkManager.getWorkInfosByTag(String) قائمة كائنات WorkInfo التي يمكن استخدامها لتحديد حالة العمل الحالية.

يعرض الرمز التالي كيفية إضافة عملية "تنظيف". علامة إلى عملك:

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .addTag("cleanup")
   .build()

Java

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
       .addTag("cleanup")
       .build();

أخيرًا، يمكن إضافة علامات متعددة إلى طلب عمل واحد. هذه العناصر داخليًا يتم تخزين العلامات كمجموعة من السلاسل. للحصول على مجموعة العلامات المرتبطة WorkRequest يمكنك استخدام WorkInfo.getTags().

من فئة Worker، يمكنك استرداد مجموعة العلامات الخاصة بها من خلال: ListenableWorker.getTags().

تحديد بيانات الإدخال

قد يتطلب عملك إدخال بيانات للقيام بعمله. على سبيل المثال، العمل الذي أنواع الصور التي يمكن أن تتطلب تحميل صورة معرف الموارد المنتظم (URI) للصورة إدخال.

يتم تخزين قيم الإدخال كأزواج المفتاح/القيمة في كائن Data. ويمكن تعيينه على طلب العمل. سيُسلِّم WorkManager الإدخال Data إلى عملك عند تنفيذ العمل. يمكن للفئة Worker الوصول إلى وسيطات الإدخال باستدعاء Worker.getInputData(). تشير رسالة الأشكال البيانية يوضح الرمز أدناه كيف يمكنك إنشاء مثيل Worker الذي بيانات الإدخال وكيفية إرسالها في طلب العمل.

Kotlin

// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()

       uploadFile(imageUriInput)
       return Result.success()
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilderU<ploadWork(>)
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   ))
   .build()

Java

// Define the Worker requiring input
public class UploadWork extends Worker {

   public UploadWork(Context appContext, WorkerParameters workerParams) {
       super(appContext, workerParams);
   }

   @NonNull
   @Override
   public Result doWork() {
       String imageUriInput = getInputData().getString("IMAGE_URI");
       if(imageUriInput == null) {
           return Result.failure();
       }

       uploadFile(imageUriInput);
       return Result.success();
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
WorkRequest myUploadWork =
      new OneTimeWorkRequest.Builder(UploadWork.class)
           .setInputData(
               new Data.Builder()
                   .putString("IMAGE_URI", "http://...")
                   .build()
           )
           .build();

وبالمثل، يمكن استخدام الفئة Data لاستخراج قيمة معروضة. إدخال و يتم تناول بيانات المخرجات بمزيد من التفصيل في القسم معلمات الإدخال القيم التي تم إرجاعها.

الخطوات التالية

في صفحة الحالات والملاحظة، ستتعرّف على المزيد من المعلومات عن حالات العمل. وكيفية مراقبة تقدم عملك.