ऐडवांस विजेट बनाएं

लिखने की सुविधा आज़माएं
Android के लिए, Jetpack Compose को यूज़र इंटरफ़ेस (यूआई) टूलकिट के तौर पर इस्तेमाल करने का सुझाव दिया जाता है. Compose-style API का इस्तेमाल करके विजेट बनाने का तरीका जानें.

इस पेज पर, उपयोगकर्ताओं को बेहतर अनुभव देने के लिए, ज़्यादा बेहतर विजेट बनाने के सबसे सही तरीकों के बारे में बताया गया है.

विजेट के कॉन्टेंट को अपडेट करने के लिए ऑप्टिमाइज़ेशन

विजेट के कॉन्टेंट को अपडेट करने में, काफ़ी कंप्यूटेशनल पावर खर्च हो सकती है. बैटरी की खपत कम करने के लिए, अपडेट के टाइप, फ़्रीक्वेंसी, और समय को ऑप्टिमाइज़ करें.

विजेट के अपडेट के टाइप

विजेट को अपडेट करने के तीन तरीके हैं: पूरा अपडेट, कुछ हिस्सा अपडेट करना, और कलेक्शन विजेट के मामले में, डेटा रीफ़्रेश करना. इनकी कंप्यूटेशनल लागत और नतीजे अलग-अलग होते हैं.

यहां हर अपडेट टाइप के बारे में बताया गया है. साथ ही, हर अपडेट टाइप के लिए कोड स्निपेट दिए गए हैं.

  • पूरा अपडेट: विजेट को पूरी तरह से अपडेट करने के लिए, AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews) को कॉल करें. इससे पहले से दिए गए RemoteViews की जगह नया RemoteViews इस्तेमाल किया जाता है. यह अपडेट, कंप्यूटिंग के हिसाब से सबसे ज़्यादा मुश्किल है.

    Kotlin

    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)

    Java

    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);
  • आंशिक अपडेट: विजेट के कुछ हिस्सों को अपडेट करने के लिए, call AppWidgetManager.partiallyUpdateAppWidget का इस्तेमाल करें. इससे नया RemoteViews, पहले से मौजूद RemoteViews के साथ मर्ज हो जाता है. अगर किसी विजेट को updateAppWidget(int[], RemoteViews) के ज़रिए कम से कम एक बार पूरा अपडेट नहीं मिलता है, तो इस तरीके को नज़रअंदाज़ कर दिया जाता है.

    Kotlin

    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)

    Java

    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);
  • कलेक्शन का डेटा रीफ़्रेश करना: अपने विजेट में मौजूद कलेक्शन व्यू के डेटा को अमान्य करने के लिए, call AppWidgetManager.notifyAppWidgetViewDataChanged का इस्तेमाल करें. इससे RemoteViewsFactory.onDataSetChanged ट्रिगर होता है. इस बीच, विजेट में पुराना डेटा दिखता है. इस तरीके से, महंगे टास्क को सुरक्षित तरीके से सिंक्रोनस तरीके से पूरा किया जा सकता है.

    Kotlin

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

    Java

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

इन तरीकों को अपने ऐप्लिकेशन में कहीं से भी कॉल किया जा सकता है. हालांकि, इसके लिए ज़रूरी है कि ऐप्लिकेशन का यूआईडी, AppWidgetProvider क्लास के यूआईडी के जैसा हो.

यह कुकी तय करती है कि विजेट को कितनी बार अपडेट किया जाए

विजेट, updatePeriodMillis एट्रिब्यूट के लिए दी गई वैल्यू के आधार पर समय-समय पर अपडेट होते हैं. उपयोगकर्ता के इंटरैक्शन, ब्रॉडकास्ट अपडेट या दोनों के जवाब में विजेट अपडेट हो सकता है.

समय-समय पर अपडेट करना

appwidget-provider एक्सएमएल में AppWidgetProviderInfo.updatePeriodMillis के लिए कोई वैल्यू तय करके, समय-समय पर होने वाले अपडेट की फ़्रीक्वेंसी को कंट्रोल किया जा सकता है. हर अपडेट, AppWidgetProvider.onUpdate() तरीके को ट्रिगर करता है. यहां विजेट को अपडेट करने के लिए कोड डाला जा सकता है. हालांकि, अगर आपके विजेट को डेटा को एसिंक्रोनस तरीके से लोड करने की ज़रूरत है या उसे अपडेट होने में 10 सेकंड से ज़्यादा समय लगता है, तो ब्रॉडकास्ट रिसीवर अपडेट के लिए उपलब्ध विकल्पों पर विचार करें. इनके बारे में यहां बताया गया है. ऐसा इसलिए, क्योंकि 10 सेकंड के बाद सिस्टम, BroadcastReceiver को जवाब न देने वाला मान लेता है.

updatePeriodMillis फ़ंक्शन, 30 मिनट से कम की वैल्यू के साथ काम नहीं करता. हालांकि, अगर आपको समय-समय पर होने वाले अपडेट बंद करने हैं, तो 0 डालें.

आपके पास उपयोगकर्ताओं को किसी कॉन्फ़िगरेशन में अपडेट की फ़्रीक्वेंसी को अडजस्ट करने की अनुमति देने का विकल्प होता है. उदाहरण के लिए, वे चाहते हैं कि स्टॉक टिकर हर 15 मिनट में अपडेट हो या सिर्फ़ चार बार अपडेट हो. इस मामले में, updatePeriodMillis को 0 पर सेट करें और इसके बजाय WorkManager का इस्तेमाल करें.

उपयोगकर्ता के इंटरैक्शन के जवाब में अपडेट करना

उपयोगकर्ता के इंटरैक्शन के आधार पर, विजेट को अपडेट करने के कुछ सुझाए गए तरीके यहां दिए गए हैं:

  • ऐप्लिकेशन की किसी गतिविधि से: उपयोगकर्ता के इंटरैक्शन के जवाब में सीधे तौर पर AppWidgetManager.updateAppWidget को कॉल करें. जैसे, उपयोगकर्ता का टैप.

  • सूचना या ऐप्लिकेशन विजेट जैसे रिमोट इंटरैक्शन से: PendingIntent बनाएं. इसके बाद, विजेट को Activity, Broadcast या Service से अपडेट करें. आपके पास अपनी प्राथमिकता चुनने का विकल्प होता है. उदाहरण के लिए, अगर आपने PendingIntent के लिए Broadcast चुना है, तो BroadcastReceiver को प्राथमिकता देने के लिए, फ़ोरग्राउंड ब्रॉडकास्ट चुना जा सकता है.

ब्रॉडकास्ट इवेंट के जवाब में अपडेट करना

ब्रॉडकास्ट इवेंट का एक उदाहरण यहां दिया गया है. इसमें अपडेट करने के लिए विजेट की ज़रूरत होती है. उदाहरण के लिए, जब उपयोगकर्ता कोई फ़ोटो लेता है. इस मामले में, आपको नई फ़ोटो का पता चलने पर विजेट को अपडेट करना है.

JobScheduler का इस्तेमाल करके कोई जॉब शेड्यूल की जा सकती है. साथ ही, JobInfo.Builder.addTriggerContentUri तरीके का इस्तेमाल करके, ब्रॉडकास्ट को ट्रिगर के तौर पर सेट किया जा सकता है.

ब्रॉडकास्ट के लिए BroadcastReceiver भी रजिस्टर किया जा सकता है. उदाहरण के लिए, ACTION_LOCALE_CHANGED को सुनना. हालांकि, इससे डिवाइस के संसाधनों का इस्तेमाल होता है. इसलिए, इसका इस्तेमाल सावधानी से करें और सिर्फ़ ब्रॉडकास्ट की गई जानकारी सुनें. Android 7.0 (एपीआई लेवल 24) और Android 8.0 (एपीआई लेवल 26) में ब्रॉडकास्ट से जुड़ी पाबंदियां लागू होने के बाद, ऐप्लिकेशन अपने मेनिफ़ेस्ट में इंप्लिसिट ब्रॉडकास्ट रजिस्टर नहीं कर सकते. हालांकि, कुछ अपवाद हैं.

BroadcastReceiver से विजेट को अपडेट करते समय ध्यान रखने वाली बातें

अगर विजेट को BroadcastReceiver से अपडेट किया जाता है, तो विजेट अपडेट करने की अवधि और प्राथमिकता के बारे में यहां दी गई बातों का ध्यान रखें. BroadcastReceiver में AppWidgetProvider भी शामिल है.

अपडेट की अवधि

आम तौर पर, सिस्टम ब्रॉडकास्ट रिसीवर को 10 सेकंड तक चलने देता है. ये रिसीवर, ऐप्लिकेशन के मुख्य थ्रेड में चलते हैं. अगर ये 10 सेकंड में पूरा नहीं होते, तो सिस्टम इन्हें रिस्पॉन्स न देने वाले रिसीवर के तौर पर मार्क कर देता है. साथ ही, ऐप्लिकेशन रिस्पॉन्स नहीं दे रहा है (एएनआर) वाली गड़बड़ी ट्रिगर कर देता है. ब्रॉडकास्ट को हैंडल करते समय, मुख्य थ्रेड को ब्लॉक करने से बचने के लिए, 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 का इस्तेमाल करके किए गए ब्रॉडकास्ट भी शामिल हैं—बैकग्राउंड प्रोसेस के तौर पर चलते हैं. इसका मतलब है कि सिस्टम के संसाधनों पर ज़्यादा लोड होने की वजह से, ब्रॉडकास्ट रिसीवर को शुरू करने में देरी हो सकती है. ब्रॉडकास्ट को प्राथमिकता देने के लिए, इसे फ़ोरग्राउंड प्रोसेस बनाएं.

उदाहरण के लिए, जब उपयोगकर्ता विजेट के किसी हिस्से पर टैप करता है, तो PendingIntent.getBroadcast को पास किए गए Intent में Intent.FLAG_RECEIVER_FOREGROUND फ़्लैग जोड़ें.