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

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

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

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

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

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

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

في ما يلي وصف لكل نوع من أنواع التعديلات مع مقتطفات الرمز لكل منها.

  • التحديث الكامل: يمكنك استدعاء 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 في ملف XML الخاص بـ appwidget-provider. يؤدي كل تحديث إلى تشغيل طريقة 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 عندما ينقر المستخدم على جزء معيّن من التطبيق المصغّر.