बैकग्राउंड में होने वाले टास्क पर सिस्टम की पाबंदियां

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

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

उपयोगकर्ता की ओर से लगाई गई पाबंदियां

अगर कोई ऐप्लिकेशन, Android की ज़रूरी जानकारी में बताई गई कुछ खराब परफ़ॉर्मेंस दिखाता है, तो सिस्टम उपयोगकर्ता को उस ऐप्लिकेशन के लिए सिस्टम के संसाधनों का ऐक्सेस सीमित करने के लिए कहता है.

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

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

डिवाइस बनाने वाली कंपनी यह तय करती है कि डिवाइस पर कौनसी पाबंदियां लगाई जाएं. उदाहरण के लिए, एओएसपी बिल्ड पर, प्रतिबंधित ऐप्लिकेशन कोई काम नहीं कर सकते, अलार्म ट्रिगर नहीं कर सकते या नेटवर्क का इस्तेमाल नहीं कर सकते. हालांकि, ऐप्लिकेशन के फ़ोरग्राउंड में होने पर ऐसा किया जा सकता है.

नेटवर्क पर की जाने वाली गतिविधि के ब्रॉडकास्ट पाने पर पाबंदियां

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

ऐसे कनेक्शन पर काम शेड्यूल करना जिनके लिए डेटा इस्तेमाल की कोई सीमा नहीं है

WorkRequest बनाते समय, NetworkType.UNMETERED Constraint जोड़ें.

fun scheduleWork(context: Context) {
    val workManager = WorkManager.getInstance(context)
    val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
        .setConstraints(
            Constraints.Builder()
                .setRequiredNetworkType(NetworkType.UNMETERED)
                .build()
        )
        .build()

    workManager.enqueue(workRequest)
}

जब आपके काम की शर्तें पूरी हो जाती हैं, तो आपके ऐप्लिकेशन को तय की गई Worker क्लास में doWork() तरीके को चलाने के लिए कॉलबैक मिलता है.

ऐप्लिकेशन के चलने के दौरान, इंटरनेट कनेक्टिविटी को मॉनिटर करना

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

NetworkRequest ऑब्जेक्ट, NetworkCapabilities के हिसाब से नेटवर्क कॉलबैक के पैरामीटर तय करते हैं. NetworkRequest.Builder क्लास की मदद से, NetworkRequest ऑब्जेक्ट बनाए जाते हैं. registerNetworkCallback इसके बाद, सिस्टम को NetworkRequest ऑब्जेक्ट पास करता है. नेटवर्क की शर्तें पूरी होने पर, ऐप्लिकेशन को कॉलबैक मिलता है. इससे, ConnectivityManager.NetworkCallback क्लास में तय किए गए onAvailable() तरीके को लागू किया जाता है.

ऐप्लिकेशन को तब तक कॉलबैक मिलते रहते हैं, जब तक कि ऐप्लिकेशन बंद नहीं हो जाता या वह unregisterNetworkCallback() को कॉल नहीं करता.

इमेज और वीडियो ब्रॉडकास्ट पाने से जुड़ी पाबंदियां

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

यह तय करना कि किस कॉन्टेंट अथॉरिटी ने काम ट्रिगर किया

WorkerParameters की मदद से, आपके ऐप्लिकेशन को इस बारे में काम की जानकारी मिलती है कि किन कॉन्टेंट अथॉरिटी और यूआरआई ने काम को ट्रिगर किया:

List<Uri> getTriggeredContentUris()

इससे उन यूआरआई की सूची दिखती है जिन्होंने काम को ट्रिगर किया है. यह खाली रहता है, अगर किसी भी यूआरआई ने काम को ट्रिगर नहीं किया है (उदाहरण के लिए, काम को ट्रिगर किया गया था समयसीमा या किसी अन्य वजह से) या बदले गए यूआरआई की संख्या इससे ज़्यादा है 50.

List<String> getTriggeredContentAuthorities()

इससे कॉन्टेंट अथॉरिटी की स्ट्रिंग लिस्ट दिखती है, जिन्होंने काम को ट्रिगर किया है. अगर वापस की गई सूची खाली नहीं है, तो getTriggeredContentUris() का इस्तेमाल करके यह जानकारी पाएं कि किन यूआरआई में बदलाव हुआ है.

यहां दिया गया सैंपल कोड, CoroutineWorker.doWork() तरीके को बदल देता है. साथ ही, कॉन्टेंट अथॉरिटी और यूआरआई को रिकॉर्ड करता है, जिन्होंने जॉब को ट्रिगर किया है:

class MyWorker(
    appContext: Context,
    private val params: WorkerParameters
) : CoroutineWorker(appContext, params) {
    override suspend fun doWork(): Result {
        StringBuilder().apply {
            append("Media content has changed:\n")
            params.triggeredContentAuthorities
                .takeIf { it.isNotEmpty() }
                ?.let { authorities ->
                    append("Authorities: ${authorities.joinToString(", ")}\n")
                    append(params.triggeredContentUris.joinToString("\n"))
                } ?: append("(No content)")
            Log.i(TAG, toString())
        }
        return Result.success()
    }
}

सिस्टम की पाबंदियों के तहत ऐप्लिकेशन की जांच करना

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

Android डीबग ब्रिज (एडीबी) के कुछ अतिरिक्त कमांड की मदद से, बैकग्राउंड में चल रही प्रोसेस को बंद करके, ऐप्लिकेशन के काम करने के तरीके की जांच की जा सकती है:

  • इंप्लिसिट ब्रॉडकास्ट और बैकग्राउंड में चलने वाली सेवाएं उपलब्ध न होने की स्थितियों को सिम्युलेट करने के लिए, यह कमांड डालें:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore

  • इंप्लिसिट ब्रॉडकास्ट और बैकग्राउंड में चलने वाली सेवाओं को फिर से चालू करने के लिए, यह कमांड डालें:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow

अपने ऐप्लिकेशन को और ऑप्टिमाइज़ करना

बैकग्राउंड में होने वाले टास्क को ऑप्टिमाइज़ करने के अन्य तरीकों के बारे में जानने के लिए, टास्क शेड्यूल करने वाले एपीआई के लिए बैटरी के इस्तेमाल को ऑप्टिमाइज़ करना लेख पढ़ें.