बैकग्राउंड में प्रोग्राम चलाने की सीमाएं

जब भी कोई ऐप्लिकेशन बैकग्राउंड में चलता है, तो वह डिवाइस के कुछ सीमित संसाधनों का इस्तेमाल करता है. जैसे, रैम. इससे उपयोगकर्ता अनुभव खराब हो सकता है. ऐसा खास तौर पर तब होता है, जब उपयोगकर्ता किसी ऐसे ऐप्लिकेशन का इस्तेमाल कर रहा हो जिसमें ज़्यादा संसाधनों की ज़रूरत होती है. जैसे, कोई गेम खेलना या वीडियो देखना. उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, Android 8.0 (एपीआई लेवल 26) में, बैकग्राउंड में चलने वाले ऐप्लिकेशन के काम करने के तरीके पर पाबंदियां लगाई गई हैं. इस दस्तावेज़ में, ऑपरेटिंग सिस्टम में हुए बदलावों के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि नई पाबंदियों के तहत ऐप्लिकेशन को बेहतर तरीके से काम करने के लिए, उसे कैसे अपडेट किया जा सकता है.

खास जानकारी

एक साथ कई Android ऐप्लिकेशन और सेवाएं चल सकती हैं. उदाहरण के लिए, कोई उपयोगकर्ता एक विंडो में गेम खेल सकता है, दूसरी विंडो में वेब ब्राउज़ कर सकता है, और तीसरे ऐप्लिकेशन का इस्तेमाल करके संगीत चला सकता है. एक साथ जितने ज़्यादा ऐप्लिकेशन चलते हैं, उतना ही ज़्यादा लोड सिस्टम पर पड़ता है. अगर बैकग्राउंड में अन्य ऐप्लिकेशन या सेवाएं चल रही हैं, तो इससे सिस्टम पर अतिरिक्त लोड पड़ता है. इसकी वजह से, उपयोगकर्ता अनुभव खराब हो सकता है. उदाहरण के लिए, हो सकता है कि संगीत ऐप्लिकेशन अचानक बंद हो जाए.

इन समस्याओं की संभावना को कम करने के लिए, Android 8.0 में यह पाबंदी लगाई गई है कि जब उपयोगकर्ता सीधे तौर पर ऐप्लिकेशन का इस्तेमाल न कर रहे हों, तब ऐप्लिकेशन क्या-क्या कर सकते हैं. ऐप्लिकेशन पर दो तरह की पाबंदियां लगाई जा सकती हैं:

  • बैकग्राउंड सेवाओं से जुड़ी सीमाएं: जब कोई ऐप्लिकेशन इस्तेमाल में नहीं होता, तब बैकग्राउंड सेवाओं के इस्तेमाल पर पाबंदियां लागू होती हैं. यह शर्त, फ़ोरग्राउंड में चलने वाली उन सेवाओं पर लागू नहीं होती जो उपयोगकर्ता को ज़्यादा दिखती हैं.

  • ब्रॉडकास्ट से जुड़ी पाबंदियां: कुछ अपवादों को छोड़कर, ऐप्लिकेशन अपने मेनिफ़ेस्ट का इस्तेमाल करके, अपने-आप होने वाले ब्रॉडकास्ट के लिए रजिस्टर नहीं कर सकते. हालांकि, वे अब भी रनटाइम के दौरान इन ब्रॉडकास्ट के लिए रजिस्टर कर सकते हैं. साथ ही, वे मैनिफ़ेस्ट का इस्तेमाल करके, अश्लील कॉन्टेंट वाले ब्रॉडकास्ट और खास तौर पर अपने ऐप्लिकेशन पर टारगेट किए गए ब्रॉडकास्ट के लिए रजिस्टर कर सकते हैं.

ज़्यादातर मामलों में, ऐप्लिकेशन JobScheduler जॉब का इस्तेमाल करके, इन सीमाओं को हल कर सकते हैं. इस तरीके से, ऐप्लिकेशन को काम करने की अनुमति तब मिलती है, जब वह चालू न हो. हालांकि, सिस्टम को इन टास्क को इस तरह से शेड्यूल करने की अनुमति मिलती है कि उपयोगकर्ता के अनुभव पर कोई असर न पड़े. Android 8.0 में JobScheduler में कई सुधार किए गए हैं. इनकी मदद से, शेड्यूल की गई सेवाओं और ब्रॉडकास्ट रिसीवर को आसानी से बदला जा सकता है. ज़्यादा जानकारी के लिए, JobScheduler में किए गए सुधार देखें.

बैकग्राउंड में चलने वाली सेवाओं से जुड़ी सीमाएं

बैकग्राउंड में चल रही सेवाएं, डिवाइस के रिसॉर्स का इस्तेमाल कर सकती हैं. इससे, उपयोगकर्ता अनुभव खराब हो सकता है. इस समस्या को कम करने के लिए, सिस्टम सेवाओं पर कई सीमाएं लागू करता है.

सिस्टम, फ़ोरग्राउंड और बैकग्राउंड ऐप्लिकेशन के बीच अंतर करता है. (सेवा से जुड़ी पाबंदियों के लिए, बैकग्राउंड की परिभाषा मेमोरी मैनेजमेंट की परिभाषा से अलग है. हो सकता है कि कोई ऐप्लिकेशन, मेमोरी मैनेजमेंट के लिए बैकग्राउंड में हो, लेकिन सेवाएं लॉन्च करने के लिए फ़ोरग्राउंड में हो.) किसी ऐप्लिकेशन को फ़ोरग्राउंड में तब माना जाता है, जब इनमें से कोई भी बात सही हो:

  • इसमें कोई गतिविधि दिखती है, भले ही वह गतिविधि शुरू की गई हो या रोकी गई हो.
  • इसमें फ़ोरग्राउंड सेवा मौजूद हो.
  • कोई दूसरा फ़ोरग्राउंड ऐप्लिकेशन, ऐप्लिकेशन से कनेक्ट हो. ऐसा, उसकी किसी सेवा से बाइंड करके या उसके कॉन्टेंट की सेवा देने वाली किसी कंपनी का इस्तेमाल करके किया जा सकता है. उदाहरण के लिए, ऐप्लिकेशन तब फ़ोरग्राउंड में होता है, जब कोई दूसरा ऐप्लिकेशन इनमें से किसी एक से बंधा हो:
    • आईएमई
    • वॉलपेपर सेवा
    • सूचना को सुनने की सुविधा
    • वॉइस या टेक्स्ट सेवा

अगर इनमें से कोई भी शर्त पूरी नहीं होती है, तो ऐप्लिकेशन को बैकग्राउंड में माना जाता है.

जब कोई ऐप्लिकेशन फ़ोरग्राउंड में होता है, तो वह फ़ोरग्राउंड और बैकग्राउंड, दोनों तरह की सेवाएं बना और चला सकता है. जब कोई ऐप्लिकेशन बैकग्राउंड में चला जाता है, तो उसके पास कुछ मिनट की विंडो होती है. इस दौरान, वह सेवाएं बना सकता है और उनका इस्तेमाल कर सकता है. इस विंडो के खत्म होने पर, ऐप्लिकेशन को इनऐक्टिव माना जाता है. इस समय, सिस्टम ऐप्लिकेशन की बैकग्राउंड सेवाओं को बंद कर देता है. ऐसा ठीक वैसे ही होता है, जैसे ऐप्लिकेशन ने सेवाओं के Service.stopSelf() तरीकों को कॉल किया हो.

कुछ मामलों में, बैकग्राउंड में चल रहे ऐप्लिकेशन को कुछ मिनट के लिए, अस्थायी अनुमति वाली सूची में रखा जाता है. जब कोई ऐप्लिकेशन अनुमति वाली सूची में शामिल होता है, तो वह बिना किसी पाबंदी के सेवाएं लॉन्च कर सकता है. साथ ही, उसकी बैकग्राउंड सेवाओं को चलने की अनुमति होती है. जब कोई ऐप्लिकेशन ऐसा टास्क मैनेज करता है जो उपयोगकर्ता को दिखता है, तो उसे अनुमति वाली सूची में शामिल किया जाता है. जैसे:

  • ज़्यादा प्राथमिकता वाले Firebase क्लाउड से मैसेज (FCM) मैसेज को मैनेज करना.
  • ब्रॉडकास्ट पाना, जैसे कि एसएमएस/एमएमएस मैसेज.
  • सूचना से PendingIntent को लागू करना.
  • वीपीएन ऐप्लिकेशन के फ़ोरग्राउंड में आने से पहले, VpnService शुरू करना.

ज़्यादातर मामलों में, आपका ऐप्लिकेशन बैकग्राउंड सेवाओं को JobScheduler जॉब से बदल सकता है. उदाहरण के लिए, CoolPhotoApp को यह देखना होगा कि उपयोगकर्ता को दोस्तों से शेयर की गई फ़ोटो मिली हैं या नहीं. भले ही, ऐप्लिकेशन फ़ोरग्राउंड में न चल रहा हो. पहले, ऐप्लिकेशन ने बैकग्राउंड में काम करने वाली ऐसी सेवा का इस्तेमाल किया था जो ऐप्लिकेशन के क्लाउड स्टोरेज की जांच करती थी. Android 8.0 (एपीआई लेवल 26) पर माइग्रेट करने के लिए, डेवलपर बैकग्राउंड सेवा को शेड्यूल की गई जॉब से बदल देता है. यह जॉब समय-समय पर लॉन्च होती है, सर्वर से क्वेरी करती है, और फिर बंद हो जाती है.

Android 8.0 से पहले, फ़ोरग्राउंड सेवा बनाने का सामान्य तरीका यह था कि पहले बैकग्राउंड सेवा बनाई जाती थी. इसके बाद, उस सेवा को फ़ोरग्राउंड में प्रमोट किया जाता था. Android 8.0 में एक समस्या है. सिस्टम, बैकग्राउंड ऐप्लिकेशन को बैकग्राउंड सेवा बनाने की अनुमति नहीं देता. इसलिए, Android 8.0 में फ़ोरग्राउंड में नई सेवा शुरू करने के लिए, startForegroundService() नाम का नया तरीका जोड़ा गया है. सिस्टम के सेवा बनाने के बाद, ऐप्लिकेशन के पास सेवा की [startForeground()](/reference/android/app/Service#startForeground(int, android.app.Notification) नई सेवा की उपयोगकर्ता को दिखने वाली सूचना दिखाने के लिए, पांच सेकंड का समय होता है. अगर ऐप्लिकेशन तय समयसीमा के अंदर startForeground() को नहीं कॉल करता है, तो सिस्टम सेवा को बंद कर देता है और ऐप्लिकेशन को ANR के तौर पर मार्क कर देता है.

ब्रॉडकास्ट से जुड़ी सीमाएं

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

  • Android 8.0 या इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन, अपने मेनिफ़ेस्ट में इंप्लिसिट ब्रॉडकास्ट के लिए ब्रॉडकास्ट रिसीवर को तब तक रजिस्टर नहीं कर सकते, जब तक कि ब्रॉडकास्ट को खास तौर पर उस ऐप्लिकेशन तक सीमित न किया गया हो. इंप्लिसिट ब्रॉडकास्ट एक ऐसा ब्रॉडकास्ट होता है जो किसी ऐप्लिकेशन के किसी खास कॉम्पोनेंट को टारगेट नहीं करता. उदाहरण के लिए, ACTION_PACKAGE_REPLACED को सभी ऐप्लिकेशन में रजिस्टर किए गए सभी लिसनर को भेजा जाता है. इससे उन्हें पता चलता है कि डिवाइस पर किसी पैकेज को बदल दिया गया है. ब्रॉडकास्ट के लिए कोई कार्रवाई नहीं की जाती है. इसलिए, यह Android 8.0 या उसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन में, मेनिफ़ेस्ट में रजिस्टर किए गए रिसीवर को डिलीवर नहीं किया जाएगा. ACTION_MY_PACKAGE_REPLACED भी एक इम्प्लीसिट ब्रॉडकास्ट है. हालांकि, इसे सिर्फ़ उस ऐप्लिकेशन को भेजा जाता है जिसका पैकेज बदला गया था. इसे मेनिफ़ेस्ट में रजिस्टर किए गए रिसीवर को डिलीवर किया जाएगा.
  • ऐप्लिकेशन, अपने मेनिफ़ेस्ट में अश्लील कॉन्टेंट वाले ब्रॉडकास्ट के लिए रजिस्टर करना जारी रख सकते हैं.
  • ऐप्लिकेशन, रनटाइम के दौरान Context.registerReceiver() का इस्तेमाल करके, किसी भी ब्रॉडकास्ट के लिए रिसीवर रजिस्टर कर सकते हैं. भले ही, वह ब्रॉडकास्ट इम्प्लीसिट हो या एक्सप्लिसिट.
  • जिन ब्रॉडकास्ट के लिए सिग्नेचर की अनुमति की ज़रूरत होती है उन पर यह पाबंदी लागू नहीं होती. ऐसा इसलिए है, क्योंकि ये ब्रॉडकास्ट सिर्फ़ उन ऐप्लिकेशन पर भेजे जाते हैं जिन्हें एक ही सर्टिफ़िकेट से साइन किया गया है, न कि डिवाइस पर मौजूद सभी ऐप्लिकेशन पर.

कई मामलों में, ऐसे ऐप्लिकेशन जिन्होंने पहले इंप्लिसिट ब्रॉडकास्ट के लिए रजिस्टर किया था वे JobScheduler जॉब का इस्तेमाल करके, मिलती-जुलती सुविधाएं पा सकते हैं. उदाहरण के लिए, सोशल फ़ोटो ऐप्लिकेशन को समय-समय पर अपने डेटा को क्लीनअप करना पड़ सकता है. साथ ही, यह ऐसा तब करना चाहता है, जब डिवाइस चार्जर से कनेक्ट हो. पहले, ऐप्लिकेशन अपने मेनिफ़ेस्ट में ACTION_POWER_CONNECTED के लिए एक रिसीवर रजिस्टर करता था. जब ऐप्लिकेशन को वह ब्रॉडकास्ट मिलता था, तो वह यह जांच करता था कि क्लीनअप ज़रूरी है या नहीं. Android 8.0 या इसके बाद के वर्शन पर माइग्रेट करने के लिए, ऐप्लिकेशन उस रिसीवर को अपने मेनिफ़ेस्ट से हटा देता है. इसके बजाय, ऐप्लिकेशन एक क्लीनअप जॉब शेड्यूल करता है, जो डिवाइस के स्क्रीन बंद होने और चार्ज होने पर चलता है.

डेटा को दूसरी जगह भेजने से जुड़ी गाइड

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

देखें कि आपका ऐप्लिकेशन, सेवाओं का इस्तेमाल कैसे करता है. अगर आपका ऐप्लिकेशन, ऐप्लिकेशन के बंद होने पर बैकग्राउंड में चलने वाली सेवाओं पर निर्भर है, तो आपको उन्हें बदलना होगा. इस समस्या को हल करने के लिए, ये तरीके अपनाए जा सकते हैं:

  • अगर आपके ऐप्लिकेशन को बैकग्राउंड में रहते हुए फ़ोरग्राउंड सेवा बनानी है, तो startService() के बजाय startForegroundService() का इस्तेमाल करें.
  • अगर उपयोगकर्ता को सेवा दिखती है, तो उसे फ़ोरग्राउंड सेवा बनाएं. उदाहरण के लिए, ऑडियो चलाने वाली सेवा हमेशा फ़ोरग्राउंड सेवा होनी चाहिए. startService() के बजाय, startForegroundService() का इस्तेमाल करके सेवा बनाएं.
  • शेड्यूल की गई किसी सेवा की सुविधा को डुप्लीकेट करने का तरीका ढूंढें. अगर सेवा, उपयोगकर्ता को तुरंत कोई काम नहीं कर रही है, तो आम तौर पर शेड्यूल की गई जॉब का इस्तेमाल किया जा सकता है.
  • बैकग्राउंड में पोलिंग करने के बजाय, नेटवर्क इवेंट होने पर अपने ऐप्लिकेशन को चुनिंदा तौर पर चालू करने के लिए, FCM का इस्तेमाल करें.
  • बैकग्राउंड में काम तब तक न करें, जब तक ऐप्लिकेशन फ़ोरग्राउंड में न हो.

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

  • मेनिफ़ेस्ट में रिसीवर का एलान करने के बजाय, Context.registerReceiver() को कॉल करके, रनटाइम के दौरान रिसीवर बनाएं.
  • शेड्यूल की गई जॉब का इस्तेमाल करके, उस शर्त की जांच करें जिसकी वजह से, इम्प्लीसिट ब्रॉडकास्ट ट्रिगर हुआ होगा.