إنشاء تطبيق مصغّر متقدّم

تجربة طريقة "إنشاء"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي يُنصح باستخدامها على Android. تعرَّف على كيفية إنشاء أدوات باستخدام واجهات برمجة التطبيقات المتوافقة مع Compose.

توضّح هذه الصفحة الممارسات المقترَحة لإنشاء أداة أكثر تقدّمًا بهدف تقديم تجربة أفضل للمستخدم.

تحسينات لتحديث محتوى التطبيق المصغّر

قد يكون تعديل محتوى التطبيق المصغّر مكلفًا من الناحية الحسابية. لتوفير استهلاك البطارية، عليك تحسين نوع التحديث ومعدّله وتوقيته.

أنواع تحديثات التطبيقات المصغّرة

هناك ثلاث طرق لتعديل أداة: تعديل كامل وتعديل جزئي، بالإضافة إلى إعادة تحميل البيانات في حال استخدام أداة مجموعة. ولكل منها تكاليف حسابية وتداعيات مختلفة.

يوضّح ما يلي كل نوع من أنواع التعديلات ويقدّم مقتطفات رمز لكل نوع.

  • التحديث الكامل: اتّصِل بالرقم AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews) لتحديث الأداة بالكامل. يؤدي هذا الإجراء إلى استبدال RemoteViews الذي تم تقديمه سابقًا برقم RemoteViews جديد. هذا هو التعديل الأكثر تكلفة من الناحية الحسابية.

val appWidgetManager = AppWidgetManager.getInstance(context)
val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply {
    setTextViewText(R.id.textview_widget_layout1, "Updated text1")
    setTextViewText(R.id.textview_widget_layout2, "Updated text2")
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews)

  • تعديل جزئي: استخدِم AppWidgetManager.partiallyUpdateAppWidget لتعديل أجزاء من الأداة. سيؤدي ذلك إلى دمج RemoteViews الجديد مع RemoteViews الذي تم تقديمه سابقًا. يتم تجاهل هذه الطريقة إذا لم يتلقَّ التطبيق المصغّر تحديثًا واحدًا على الأقل من خلال updateAppWidget(int[], RemoteViews).

val appWidgetManager = AppWidgetManager.getInstance(context)
val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply {
    setTextViewText(R.id.textview_widget_layout, "Updated text")
}
appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)

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

val appWidgetManager = AppWidgetManager.getInstance(context)
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)

يمكنك استدعاء هذه الطرق من أي مكان في تطبيقك، طالما أنّ التطبيق لديه معرّف UID نفسه مثل فئة AppWidgetProvider المقابلة.

تحديد عدد مرات تحديث أداة

يتم تعديل التطبيقات المصغّرة بشكل دوري استنادًا إلى القيمة المقدَّمة للسمة updatePeriodMillis. يمكن أن يتم تعديل التطبيق المصغّر استجابةً لتفاعل المستخدم أو بث التعديلات أو كليهما.

التحديث بشكل دوري

يمكنك التحكّم في معدّل تكرار التحديث الدوري من خلال تحديد قيمة AppWidgetProviderInfo.updatePeriodMillis في ملف appwidget-provider بتنسيق XML. يؤدي كل تحديث إلى تشغيل طريقة AppWidgetProvider.onUpdate()، وهي المكان الذي يمكنك فيه وضع الرمز لتحديث الأداة. ومع ذلك، ننصحك بالاطّلاع على بدائل لتحديثات مستقبِل البث الموضّحة في القسم التالي إذا كانت الأداة تحتاج إلى تحميل البيانات بشكل غير متزامن أو تستغرق أكثر من 10 ثوانٍ للتحديث، لأنّه بعد 10 ثوانٍ، يعتبر النظام BroadcastReceiver غير مستجيب.

لا تتيح الدالة updatePeriodMillis استخدام قيم أقل من 30 دقيقة. ومع ذلك، إذا أردت إيقاف التحديثات الدورية، يمكنك تحديد القيمة 0.

يمكنك السماح للمستخدمين بضبط عدد مرات التحديث في الإعدادات. على سبيل المثال، قد يريدون تحديث مؤشر أسعار الأسهم كل 15 دقيقة أو أربع مرات فقط في اليوم. في هذه الحالة، اضبط updatePeriodMillis على 0 واستخدِم WorkManager بدلاً من ذلك.

تعديل استجابةً لتفاعل المستخدم

في ما يلي بعض الطرق المقترَحة لتعديل الأداة استنادًا إلى تفاعل المستخدم:

  • من نشاط التطبيق: استدعاء AppWidgetManager.updateAppWidget مباشرةً استجابةً لتفاعل المستخدم، مثل نقرة المستخدم.

  • من التفاعلات عن بُعد، مثل الإشعارات أو أدوات التطبيقات: أنشئ PendingIntent، ثم عدِّل الأداة من Activity أو Broadcast أو Service الذي تم استدعاؤه. يمكنك اختيار الأولوية التي تريدها. على سبيل المثال، إذا اخترت Broadcast لـ PendingIntent، يمكنك اختيار بث في المقدّمة لمنح BroadcastReceiver الأولوية.

تعديل استجابة لحدث بث

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

يمكنك تحديد موعد لتنفيذ العمل باستخدام WorkManager وتحديد مشغّل معرّف موارد منتظم للمحتوى باستخدام الطريقة Constraints.Builder.addContentUriTrigger.

يمكنك أيضًا تسجيل BroadcastReceiver للبث، مثلاً، الاستماع إلى ACTION_LOCALE_CHANGED. ومع ذلك، بما أنّ هذه العملية تستهلك موارد الجهاز، يجب استخدامها بحذر والاستماع فقط إلى البث المحدّد. مع طرح قيود البث في الإصدار 7.0 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 24) والإصدار 8.0 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 26)، لا يمكن للتطبيقات تسجيل عمليات البث الضمنية في بياناتها، مع بعض الاستثناءات.

اعتبارات عند تعديل تطبيق مصغّر من BroadcastReceiver

إذا تم تحديث التطبيق المصغَّر من BroadcastReceiver، بما في ذلك AppWidgetProvider، يجب الانتباه إلى الاعتبارات التالية بشأن مدة تحديث التطبيق المصغَّر وأولويته.

مدة التحديث

كقاعدة عامة، يسمح النظام لمستقبِلات البث، التي تعمل عادةً في سلسلة التعليمات الرئيسية للتطبيق، بالعمل لمدة تصل إلى 10 ثوانٍ قبل اعتبارها غير مستجيبة وتفعيل خطأ التطبيق لا يستجيب (ANR). لتجنُّب حظر سلسلة التعليمات الرئيسية أثناء معالجة البث، استخدِم طريقة goAsync. إذا استغرقت عملية تعديل التطبيق المصغّر وقتًا أطول، ننصحك بجدولة مهمة باستخدام WorkManager.

Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.

لمزيد من المعلومات، يُرجى الاطّلاع على اعتبارات الأمان وأفضل الممارسات.

أولوية التحديث

تُنفَّذ عمليات البث، بما في ذلك عمليات البث التي تتم باستخدام AppWidgetProvider.onUpdate، كعمليات في الخلفية بشكلٍ تلقائي. وهذا يعني أنّ موارد النظام المحمّلة بشكل زائد يمكن أن تتسبّب في تأخير استدعاء أداة استقبال البث. لإعطاء الأولوية للبث، اجعله عملية في المقدّمة.

على سبيل المثال، أضِف العلامة Intent.FLAG_RECEIVER_FOREGROUND إلى Intent التي تم تمريرها إلى PendingIntent.getBroadcast عندما ينقر المستخدم على جزء معيّن من التطبيق المصغّر.