یک ویجت پیشرفته ایجاد کنید

روش نوشتن را امتحان کنید
Jetpack Compose ابزار رابط کاربری پیشنهادی برای اندروید است. یاد بگیرید که چگونه با استفاده از APIهای سبک Compose، ویجت بسازید.

این صفحه شیوه‌های پیشنهادی برای ایجاد یک ویجت پیشرفته‌تر برای تجربه کاربری بهتر را توضیح می‌دهد.

بهینه‌سازی‌ها برای به‌روزرسانی محتوای ویجت

به‌روزرسانی محتوای ویجت می‌تواند از نظر محاسباتی پرهزینه باشد. برای صرفه‌جویی در مصرف باتری، نوع، فرکانس و زمان به‌روزرسانی را بهینه کنید.

انواع به‌روزرسانی‌های ویجت

سه راه برای به‌روزرسانی یک ویجت وجود دارد: به‌روزرسانی کامل، به‌روزرسانی جزئی و در مورد ویجت‌های مجموعه، به‌روزرسانی داده‌ها. هر کدام هزینه‌ها و پیامدهای محاسباتی متفاوتی دارند.

در ادامه هر نوع به‌روزرسانی شرح داده شده و قطعه کدی برای هر کدام ارائه شده است.

  • به‌روزرسانی کامل: برای به‌روزرسانی کامل ویجت AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews) را فراخوانی کنید. این کار RemoteViews ارائه شده قبلی را با RemoteViews جدید جایگزین می‌کند. این به‌روزرسانی از نظر محاسباتی پرهزینه‌ترین به‌روزرسانی است.

    کاتلین

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

    جاوا

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
    remoteViews.setTextViewText(R.id.textview_widget_layout1, "Updated text1");
    remoteViews.setTextViewText(R.id.textview_widget_layout2, "Updated text2");
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
  • Partial update: call AppWidgetManager.partiallyUpdateAppWidget to update parts of the widget. This merges the new RemoteViews with the previously provided RemoteViews . This method is ignored if a widget doesn't receive at least one full update through updateAppWidget(int[], RemoteViews) .

    کاتلین

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

    جاوا

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
    remoteViews.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)

    جاوا

    AppWidgetManager 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 را تعیین کنید.

شما می‌توانید به کاربران اجازه دهید تعداد دفعات به‌روزرسانی‌ها را در یک پیکربندی تنظیم کنند. برای مثال، ممکن است بخواهند یک شاخص سهام هر ۱۵ دقیقه یا فقط چهار بار در روز به‌روزرسانی شود. در این حالت، updatePeriodMillis را روی ۰ تنظیم کنید و به جای آن از WorkManager استفاده کنید.

به‌روزرسانی در پاسخ به تعامل کاربر

در اینجا چند روش پیشنهادی برای به‌روزرسانی ویجت بر اساس تعامل کاربر ارائه شده است:

  • از یک فعالیت برنامه: مستقیماً AppWidgetManager.updateAppWidget در پاسخ به تعامل کاربر، مانند ضربه زدن کاربر، فراخوانی کنید.

  • از تعاملات از راه دور، مانند یک اعلان یا یک ویجت برنامه: یک PendingIntent بسازید، سپس ویجت را از Activity ، Broadcast یا Service فراخوانی شده به‌روزرسانی کنید. می‌توانید اولویت خودتان را انتخاب کنید. برای مثال، اگر Broadcast برای PendingIntent انتخاب کنید، می‌توانید یک broadcast پیش‌زمینه برای اولویت دادن به BroadcastReceiver انتخاب کنید.

به‌روزرسانی در پاسخ به یک رویداد پخش

یک نمونه از رویداد پخش که نیاز به به‌روزرسانی ویجت دارد، زمانی است که کاربر عکس می‌گیرد. در این حالت، شما می‌خواهید ویجت را هنگام شناسایی یک عکس جدید به‌روزرسانی کنید.

شما می‌توانید یک کار را با JobScheduler زمان‌بندی کنید و با استفاده از متد JobInfo.Builder.addTriggerContentUri یک broadcast را به عنوان trigger مشخص کنید.

همچنین می‌توانید یک BroadcastReceiver برای broadcast ثبت کنید - برای مثال، به ACTION_LOCALE_CHANGED گوش دهید. با این حال، از آنجا که این کار منابع دستگاه را مصرف می‌کند، از آن با احتیاط استفاده کنید و فقط به broadcast خاص گوش دهید. با معرفی محدودیت‌های broadcast در اندروید ۷.۰ (API سطح ۲۴) و اندروید ۸.۰ (API سطح ۲۶)، برنامه‌ها نمی‌توانند broadcastهای ضمنی را در manifests خود ثبت کنند، به جز موارد استثنا .

ملاحظات هنگام به‌روزرسانی یک ویجت از 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 اضافه کنید.