Android 7.0 के व्यवहार में बदलाव

Android 7.0 में नई सुविधाओं और क्षमताओं के साथ-साथ, सिस्टम और एपीआई के काम करने के तरीके में कई बदलाव किए गए हैं. इस दस्तावेज़ में कुछ अहम बदलावों के बारे में बताया गया है. आपको इन बदलावों को समझना चाहिए और अपने ऐप्लिकेशन में इन्हें लागू करना चाहिए.

अगर आपने पहले Android के लिए कोई ऐप्लिकेशन पब्लिश किया है, तो ध्यान रखें कि प्लैटफ़ॉर्म में हुए इन बदलावों का असर आपके ऐप्लिकेशन पर पड़ सकता है.

बैटरी और मेमोरी

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

बैटरी बचाएं (डोज़)

Android 6.0 (एपीआई लेवल 23) में पेश की गई बैटरी बचाने की सुविधा, बैटरी लाइफ़ को बेहतर बनाती है. इसके लिए, जब कोई उपयोगकर्ता डिवाइस को अनप्लग करके, बिना हिलाए-डुलाए, और स्क्रीन बंद करके छोड़ देता है, तो सीपीयू और नेटवर्क पर की जाने वाली गतिविधि को रोक दिया जाता है. Android 7.0 में, बैटरी बचाने की सुविधा को और बेहतर बनाया गया है. इसके लिए, सीपीयू और नेटवर्क पर कुछ पाबंदियां लगाई गई हैं. ये पाबंदियां तब लागू होती हैं, जब डिवाइस को अनप्लग किया गया हो और उसकी स्क्रीन बंद हो. हालांकि, इसके लिए डिवाइस का बिना हिले-डुले रहना ज़रूरी नहीं है. उदाहरण के लिए, जब कोई हैंडसेट उपयोगकर्ता की जेब में हो.

इस इलस्ट्रेशन में दिखाया गया है कि बैटरी लाइफ़ बढ़ाने के लिए, बैटरी बचाएं सुविधा किस तरह सिस्टम की गतिविधि पर पहले लेवल की पाबंदियां लगाती है

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

जब कोई डिवाइस बैटरी पावर पर होता है और स्क्रीन कुछ समय के लिए बंद रहती है, तो डिवाइस बैटरी बचाने वाले मोड में चला जाता है. साथ ही, पाबंदियों का पहला सबसेट लागू करता है: यह ऐप्लिकेशन के नेटवर्क ऐक्सेस को बंद कर देता है. साथ ही, जॉब और सिंक को रोक देता है. अगर बैटरी बचाने की सुविधा चालू होने के बाद, डिवाइस कुछ समय तक इस्तेमाल नहीं किया जाता है, तो सिस्टम PowerManager.WakeLock, AlarmManager अलार्म, जीपीएस, और वाई-फ़ाई स्कैन पर, बैटरी बचाने की सुविधा से जुड़ी बाकी पाबंदियां लागू कर देता है. 'बैटरी बचाएं' सुविधा की कुछ या सभी पाबंदियां लागू होने के बावजूद, सिस्टम कुछ समय के लिए डिवाइस को चालू करता है. इस दौरान, ऐप्लिकेशन को नेटवर्क ऐक्सेस करने की अनुमति दी जाती है. साथ ही, वे रोके गए किसी भी काम/सिंक को पूरा कर सकते हैं.

इस इलस्ट्रेशन में दिखाया गया है कि डिवाइस के कुछ समय तक इस्तेमाल न होने पर, बैटरी बचाने की सुविधा किस तरह सिस्टम की गतिविधि पर दूसरे लेवल की पाबंदियां लगाती है

दूसरी इमेज. इस इलस्ट्रेशन में दिखाया गया है कि डिवाइस के कुछ समय तक इस्तेमाल न होने पर, बैटरी बचाने की सुविधा किस तरह सिस्टम की गतिविधि पर दूसरे लेवल की पाबंदियां लागू करती है.

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

Project Svelte: बैकग्राउंड ऑप्टिमाइज़ेशन

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

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

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

इन समस्याओं को कम करने के लिए, Android 7.0 में ये ऑप्टिमाइज़ेशन लागू किए गए हैं:

  • Android 7.0 (एपीआई लेवल 24) और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन को CONNECTIVITY_ACTION ब्रॉडकास्ट नहीं मिलते. ऐसा तब होता है, जब वे मेनिफ़ेस्ट में अपने ब्रॉडकास्ट रिसीवर का एलान करते हैं. ऐप्लिकेशन को अब भी CONNECTIVITY_ACTION ब्रॉडकास्ट मिलेंगे. इसके लिए, उन्हें Context.registerReceiver() के साथ BroadcastReceiver को रजिस्टर करना होगा. साथ ही, यह ज़रूरी है कि वह कॉन्टेक्स्ट अब भी मान्य हो.
  • सिस्टम अब ACTION_NEW_PICTURE या ACTION_NEW_VIDEO ब्रॉडकास्ट नहीं भेजता. इस ऑप्टिमाइज़ेशन का असर सभी ऐप्लिकेशन पर पड़ता है, न कि सिर्फ़ Android 7.0 को टारगेट करने वाले ऐप्लिकेशन पर.

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

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

अनुमतियों में बदलाव

Android 7.0 में अनुमतियों से जुड़े बदलाव शामिल हैं. इनसे आपके ऐप्लिकेशन पर असर पड़ सकता है.

फ़ाइल सिस्टम की अनुमति में बदलाव

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

  • निजी फ़ाइलों के मालिक को अब फ़ाइल से जुड़ी अनुमतियों में ढील नहीं देनी चाहिए. MODE_WORLD_READABLE और/या MODE_WORLD_WRITEABLE का इस्तेमाल करके ऐसा करने की कोशिश करने पर, SecurityException ट्रिगर होगा.

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

  • पैकेज डोमेन के बाहर file:// यूआरआई पास करने से, रिसीवर को ऐसा पाथ मिल सकता है जिसे ऐक्सेस नहीं किया जा सकता. इसलिए, file:// यूआरआई को पास करने की कोशिश करने पर, FileUriExposedException ट्रिगर होता है. किसी निजी फ़ाइल का कॉन्टेंट शेयर करने के लिए, FileProvider का इस्तेमाल करने का सुझाव दिया जाता है.
  • DownloadManager अब निजी तौर पर सेव की गई फ़ाइलों को उनके नाम से शेयर नहीं कर सकता. COLUMN_LOCAL_FILENAME को ऐक्सेस करते समय, लेगसी ऐप्लिकेशन को ऐसा पाथ मिल सकता है जिसे ऐक्सेस नहीं किया जा सकता. Android 7.0 या इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन, COLUMN_LOCAL_FILENAME को ऐक्सेस करने की कोशिश करते समय SecurityException को ट्रिगर करते हैं. ऐसे लेगसी ऐप्लिकेशन जो DownloadManager.Request.setDestinationInExternalFilesDir() या DownloadManager.Request.setDestinationInExternalPublicDir() का इस्तेमाल करके, डाउनलोड की गई फ़ाइलों को सेव करने की जगह को सार्वजनिक जगह के तौर पर सेट करते हैं वे अब भी COLUMN_LOCAL_FILENAME में पाथ को ऐक्सेस कर सकते हैं. हालांकि, इस तरीके का इस्तेमाल करने से बचें. DownloadManager से मिली फ़ाइल को ऐक्सेस करने का सबसे सही तरीका, ContentResolver.openFileDescriptor() का इस्तेमाल करना है.

ऐप्लिकेशन के बीच फ़ाइलें शेयर करना

Android 7.0 को टारगेट करने वाले ऐप्लिकेशन के लिए, Android फ़्रेमवर्क StrictMode एपीआई नीति को लागू करता है. यह नीति, आपके ऐप्लिकेशन के बाहर file:// यूआरआई को एक्सपोज़ करने पर पाबंदी लगाती है. अगर फ़ाइल यूआरआई वाला कोई इंटेंट आपके ऐप्लिकेशन से बाहर जाता है, तो ऐप्लिकेशन FileUriExposedException अपवाद के साथ काम नहीं करता.

ऐप्लिकेशन के बीच फ़ाइलें शेयर करने के लिए, आपको content:// यूआरआई भेजना चाहिए. साथ ही, यूआरआई को कुछ समय के लिए ऐक्सेस करने की अनुमति देनी चाहिए. यह अनुमति देने का सबसे आसान तरीका है, FileProvider क्लास का इस्तेमाल करना. अनुमतियों और फ़ाइलें शेयर करने के बारे में ज़्यादा जानने के लिए, फ़ाइलें शेयर करना लेख पढ़ें.

सुलभता सुविधाओं में सुधार

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

स्क्रीन ज़ूम

Android 7.0 में, उपयोगकर्ता डिसप्ले का साइज़ सेट कर सकते हैं. इससे स्क्रीन पर मौजूद सभी एलिमेंट को बड़ा या छोटा किया जा सकता है. इससे कम दृष्टि वाले उपयोगकर्ताओं के लिए, डिवाइस को ऐक्सेस करना आसान हो जाता है. उपयोगकर्ता स्क्रीन को sw320dp की कम से कम चौड़ाई से ज़्यादा ज़ूम नहीं कर सकते. यह Nexus 4 की चौड़ाई है, जो कि सामान्य तौर पर इस्तेमाल होने वाला मध्यम साइज़ का फ़ोन है.

Android 7.0 सिस्टम इमेज वाले डिवाइस पर, ज़ूम किए बिना डिसप्ले साइज़ दिखाने वाली स्क्रीन
Android 7.0 सिस्टम इमेज वाले डिवाइस पर, डिसप्ले का साइज़ बढ़ाने का असर दिखाने वाली स्क्रीन

तीसरी इमेज. दाईं ओर मौजूद स्क्रीन पर, Android 7.0 सिस्टम इमेज वाले डिवाइस के डिसप्ले का साइज़ बढ़ाने का असर दिखाया गया है.

डिवाइस की डेंसिटी बदलने पर, सिस्टम चल रहे ऐप्लिकेशन को इन तरीकों से सूचना देता है:

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

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

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

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

  • डाइमेंशन को px यूनिट में तय करने से बचें, क्योंकि वे स्क्रीन डेंसिटी के हिसाब से स्केल नहीं होते. इसके बजाय, डाइमेंशन को डेंसिटी-इंडिपेंडेंट पिक्सल (dp) यूनिट में तय करें.

सेटअप विज़र्ड में डिसप्ले से जुड़ी सेटिंग

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

प्लैटफ़ॉर्म लाइब्रेरी से लिंक करने वाले एनडीके ऐप्लिकेशन

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

आपका ऐप्लिकेशन, निजी प्लैटफ़ॉर्म एपीआई को तीन तरीकों से ऐक्सेस करने की कोशिश कर सकता है:

  • आपका ऐप्लिकेशन, निजी प्लैटफ़ॉर्म लाइब्रेरी को सीधे तौर पर ऐक्सेस करता है. आपको अपने ऐप्लिकेशन को अपडेट करना चाहिए, ताकि उसमें उन लाइब्रेरी की कॉपी शामिल की जा सके या सार्वजनिक एनडीके एपीआई का इस्तेमाल किया जा सके.
  • आपका ऐप्लिकेशन, तीसरे पक्ष की ऐसी लाइब्रेरी का इस्तेमाल करता है जो निजी प्लैटफ़ॉर्म की लाइब्रेरी को ऐक्सेस करती है. भले ही आपको पक्का पता हो कि आपका ऐप्लिकेशन सीधे तौर पर निजी लाइब्रेरी को ऐक्सेस नहीं करता है, फिर भी आपको इस स्थिति के लिए अपने ऐप्लिकेशन की जांच करनी चाहिए.
  • आपका ऐप्लिकेशन किसी ऐसी लाइब्रेरी का रेफ़रंस देता है जो उसके APK में शामिल नहीं है. उदाहरण के लिए, ऐसा तब हो सकता है, जब आपने OpenSSL की अपनी कॉपी इस्तेमाल करने की कोशिश की हो, लेकिन उसे अपने ऐप्लिकेशन के APK के साथ बंडल करना भूल गए हों. यह ऐप्लिकेशन, Android प्लैटफ़ॉर्म के उन वर्शन पर सामान्य रूप से काम कर सकता है जिनमें libcrypto.so शामिल है. हालांकि, Android के उन नए वर्शन पर ऐप्लिकेशन क्रैश हो सकता है जिनमें यह लाइब्रेरी शामिल नहीं है. जैसे, Android 6.0 और इसके बाद के वर्शन. इस समस्या को ठीक करने के लिए, पक्का करें कि आपने अपनी सभी नॉन-एनडीके लाइब्रेरी को अपने APK के साथ बंडल किया हो.

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

इस पाबंदी का असर, फ़िलहाल रिलीज़ किए गए ऐप्लिकेशन पर कम से कम पड़े, इसके लिए ज़्यादा इस्तेमाल की जाने वाली लाइब्रेरी के सेट को Android 7.0 (एपीआई लेवल 24) पर कुछ समय के लिए ऐक्सेस किया जा सकता है. ये लाइब्रेरी, एपीआई लेवल 23 या इससे पहले के लेवल को टारगेट करने वाले ऐप्लिकेशन के लिए उपलब्ध हैं. इन लाइब्रेरी में, libandroid_runtime.so, libcutils.so, libcrypto.so, और libssl.so शामिल हैं. अगर आपका ऐप्लिकेशन इनमें से कोई लाइब्रेरी लोड करता है, तो logcat एक चेतावनी जनरेट करता है. साथ ही, आपको सूचना देने के लिए टारगेट डिवाइस पर एक टोस्ट दिखता है. अगर आपको ये चेतावनियां दिखती हैं, तो आपको अपने ऐप्लिकेशन को अपडेट करना चाहिए. इसके लिए, उन लाइब्रेरी की अपनी कॉपी शामिल करें या सिर्फ़ सार्वजनिक एनडीके एपीआई का इस्तेमाल करें. Android प्लैटफ़ॉर्म के आने वाले वर्शन में, निजी लाइब्रेरी के इस्तेमाल पर पूरी तरह से पाबंदी लगाई जा सकती है. इससे आपका ऐप्लिकेशन क्रैश हो सकता है.

सभी ऐप्लिकेशन, रनटाइम से जुड़ी गड़बड़ी तब जनरेट करते हैं, जब वे किसी ऐसे एपीआई को कॉल करते हैं जो न तो सार्वजनिक है और न ही कुछ समय के लिए ऐक्सेस किया जा सकता है. नतीजा यह होता है कि System.loadLibrary और dlopen(3), दोनों NULL दिखाते हैं. इससे आपका ऐप्लिकेशन क्रैश हो सकता है. आपको अपने ऐप्लिकेशन के कोड की समीक्षा करनी चाहिए, ताकि निजी प्लैटफ़ॉर्म एपीआई का इस्तेमाल हटाया जा सके. साथ ही, Android 7.0 (एपीआई लेवल 24) पर चलने वाले डिवाइस या एम्युलेटर का इस्तेमाल करके, अपने ऐप्लिकेशन की अच्छी तरह से जांच करनी चाहिए. अगर आपको पक्का नहीं है कि आपका ऐप्लिकेशन निजी लाइब्रेरी का इस्तेमाल करता है या नहीं, तो रनटाइम से जुड़ी गड़बड़ी की पहचान करने के लिए, Logcat की जांच की जा सकती है.

यहां दी गई टेबल में बताया गया है कि किसी ऐप्लिकेशन के काम करने का तरीका कैसा होना चाहिए. यह इस बात पर निर्भर करता है कि वह निजी नेटिव लाइब्रेरी और टारगेट एपीआई लेवल (android:targetSdkVersion) का इस्तेमाल कैसे करता है.

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

यह देखना कि आपका ऐप्लिकेशन निजी लाइब्रेरी का इस्तेमाल करता है या नहीं

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

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

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

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)

अगर आपका ऐप्लिकेशन, तीसरे पक्ष की ऐसी लाइब्रेरी का इस्तेमाल करता है जो निजी प्लैटफ़ॉर्म एपीआई से डाइनैमिक तौर पर लिंक होती हैं, तो आपको ये logcat आउटपुट भी दिख सकते हैं. Android 7.0 एनडीके में मौजूद readelf टूल की मदद से, डाइनैमिक तौर पर लिंक की गई सभी शेयर की गई लाइब्रेरी की सूची जनरेट की जा सकती है. इसके लिए, आपको यहां दिया गया कमांड चलाकर, .so फ़ाइल को जनरेट करना होगा:

aarch64-linux-android-readelf -dW libMyLibrary.so

अपना ऐप्लिकेशन अपडेट करें

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

  • अगर आपका ऐप्लिकेशन निजी प्लैटफ़ॉर्म लाइब्रेरी का इस्तेमाल करता है, तो आपको उसे अपडेट करना चाहिए, ताकि उन लाइब्रेरी की अपनी कॉपी शामिल की जा सके या सार्वजनिक एनडीके एपीआई का इस्तेमाल किया जा सके.
  • अगर आपका ऐप्लिकेशन, तीसरे पक्ष की ऐसी लाइब्रेरी का इस्तेमाल करता है जो निजी सिंबल को ऐक्सेस करती है, तो लाइब्रेरी को अपडेट करने के लिए, लाइब्रेरी के लेखक से संपर्क करें.
  • पक्का करें कि आपने अपनी सभी नॉन-एनडीके लाइब्रेरी को APK के साथ पैकेज किया हो.
  • libandroid_runtime.so से getJavaVM और getJNIEnv के बजाय, स्टैंडर्ड जेएनआई फ़ंक्शन का इस्तेमाल करें:
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • libcutils.so में मौजूद निजी property_get सिंबल के बजाय, __system_property_get का इस्तेमाल करें. इसके लिए, __system_property_get का इस्तेमाल करें. साथ ही, इसमें यह शामिल करें:
    #include <sys/system_properties.h>

    ध्यान दें: सीटीएस की मदद से, सिस्टम प्रॉपर्टी की उपलब्धता और कॉन्टेंट की जांच नहीं की जाती. इन प्रॉपर्टी का इस्तेमाल न करना ही सबसे बेहतर तरीका है.

  • libcrypto.so से SSL_ctrl सिंबल के स्थानीय वर्शन का इस्तेमाल करें. उदाहरण के लिए, आपको अपनी .so फ़ाइल में libcyrpto.a को स्टैटिक तौर पर लिंक करना चाहिए या BoringSSL/OpenSSL से libcrypto.so के डाइनैमिक तौर पर लिंक किए गए वर्शन को शामिल करना चाहिए और उसे अपने APK में पैकेज करना चाहिए.

Android for Work

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

  • डीपीसी के सेट करने से पहले, आपको डेलिगेट किया गया सर्टिफ़िकेट इंस्टॉलर इंस्टॉल करना होगा. Android 7.0 (एपीआई लेवल 24) को टारगेट करने वाले प्रोफ़ाइल और डिवाइस के मालिक के ऐप्लिकेशन, दोनों के लिए आपको डेलिगेट किया गया सर्टिफ़िकेट इंस्टॉलर इंस्टॉल करना चाहिए. ऐसा डिवाइस नीति कंट्रोलर (डीपीसी) के DevicePolicyManager.setCertInstallerPackage() को कॉल करने से पहले करना चाहिए. अगर इंस्टॉलर पहले से इंस्टॉल नहीं है, तो सिस्टम IllegalArgumentException दिखाता है.
  • डिवाइस एडमिन के लिए पासवर्ड रीसेट करने से जुड़ी पाबंदियां, अब प्रोफ़ाइल के मालिकों पर लागू होती हैं. डिवाइस एडमिन, अब पासवर्ड हटाने या पहले से सेट किए गए पासवर्ड बदलने के लिए, DevicePolicyManager.resetPassword() का इस्तेमाल नहीं कर सकते. डिवाइस एडमिन अब भी पासवर्ड सेट कर सकते हैं. हालांकि, ऐसा सिर्फ़ तब किया जा सकता है, जब डिवाइस पर कोई पासवर्ड, पिन या पैटर्न सेट न हो.
  • डिवाइस और प्रोफ़ाइल के मालिक, खातों को मैनेज कर सकते हैं. भले ही, उन पर पाबंदियां सेट की गई हों. डिवाइस के मालिक और प्रोफ़ाइल के मालिक, Account Management API को कॉल कर सकते हैं. भले ही, DISALLOW_MODIFY_ACCOUNTS उपयोगकर्ता पर पाबंदियां लागू हों.
  • डिवाइस के मालिक, सेकंडरी उपयोगकर्ताओं को मैनेज कर सकते हैं. जब कोई डिवाइस, डिवाइस के मालिक वाले मोड में चल रहा होता है, तो DISALLOW_ADD_USER पर पाबंदी अपने-आप सेट हो जाती है. इससे उपयोगकर्ता, मैनेज नहीं किए जा रहे सेकंडरी उपयोगकर्ता नहीं बना पाते. इसके अलावा, CreateUser() और createAndInitializeUser() तरीके अब काम नहीं करते. इनकी जगह, अब DevicePolicyManager.createAndManageUser() तरीका इस्तेमाल किया जाता है.
  • डिवाइस के मालिक, डिवाइस आइडेंटिफ़ायर ऐक्सेस कर सकते हैं. डिवाइस का मालिक, DevicePolicyManager.getWifiMacAddress() का इस्तेमाल करके डिवाइस के वाई-फ़ाई का मैक पता ऐक्सेस कर सकता है. अगर डिवाइस पर वाई-फ़ाई कभी चालू नहीं किया गया है, तो यह तरीका null की वैल्यू दिखाता है.
  • वर्क मोड की सेटिंग से, वर्क ऐप्लिकेशन के ऐक्सेस को कंट्रोल किया जाता है. वर्क मोड बंद होने पर, सिस्टम लॉन्चर वर्क ऐप्लिकेशन को धूसर करके दिखाता है. इससे पता चलता है कि वे उपलब्ध नहीं हैं. वर्क मोड को फिर से चालू करने पर, सामान्य व्यवहार वापस आ जाता है.
  • सेटिंग यूज़र इंटरफ़ेस (यूआई) से, क्लाइंट सर्टिफ़िकेट चेन और उससे जुड़ी निजी पासकोड वाली PKCS #12 फ़ाइल इंस्टॉल करने पर, चेन में मौजूद सीए सर्टिफ़िकेट अब भरोसेमंद क्रेडेंशियल स्टोरेज में इंस्टॉल नहीं होता है. इससे KeyChain.getCertificateChain() के नतीजे पर कोई असर नहीं पड़ता है. ऐसा तब होता है, जब ऐप्लिकेशन बाद में क्लाइंट सर्टिफ़िकेट चेन को वापस पाने की कोशिश करते हैं. अगर ज़रूरी हो, तो सीए सर्टिफ़िकेट को भरोसेमंद क्रेडेंशियल स्टोरेज में इंस्टॉल किया जाना चाहिए. इसके लिए, सेटिंग यूज़र इंटरफ़ेस (यूआई) का अलग से इस्तेमाल करें. साथ ही, .crt या .cer फ़ाइल एक्सटेंशन के तहत, डीईआर-एन्कोडेड फ़ॉर्मैट का इस्तेमाल करें.
  • Android 7.0 से, फ़िंगरप्रिंट को रजिस्टर करने और स्टोरेज को मैनेज करने की सुविधा, हर उपयोगकर्ता के लिए उपलब्ध है. अगर प्रोफ़ाइल के मालिक का डिवाइस पॉलिसी क्लाइंट (डीपीसी), Android 7.0 (एपीआई लेवल 24) पर चलने वाले डिवाइस पर एपीआई लेवल 23 (या इससे पहले के वर्शन) को टारगेट करता है, तो उपयोगकर्ता अब भी डिवाइस पर फ़िंगरप्रिंट सेट कर सकता है. हालांकि, ऑफ़िस के ऐप्लिकेशन, डिवाइस के फ़िंगरप्रिंट को ऐक्सेस नहीं कर सकते. जब डीपीसी, एपीआई लेवल 24 और उसके बाद के वर्शन को टारगेट करता है, तो उपयोगकर्ता सेटिंग > सुरक्षा > वर्क प्रोफ़ाइल की सुरक्षा पर जाकर, खास तौर पर वर्क प्रोफ़ाइल के लिए फ़िंगरप्रिंट सेट कर सकता है.
  • DevicePolicyManager.getStorageEncryptionStatus(), एन्क्रिप्शन की नई स्थिति ENCRYPTION_STATUS_ACTIVE_PER_USER दिखाता है. इससे पता चलता है कि एन्क्रिप्शन की सुविधा चालू है और एन्क्रिप्शन कुंजी, उपयोगकर्ता से जुड़ी है. नया स्टेटस सिर्फ़ तब दिखता है, जब DPC, टारगेट एपीआई लेवल 24 और इसके बाद के वर्शन को टारगेट करता है. पुराने एपीआई लेवल को टारगेट करने वाले ऐप्लिकेशन के लिए, ENCRYPTION_STATUS_ACTIVE दिखाया जाता है. भले ही, एन्क्रिप्शन पासकोड किसी उपयोगकर्ता या प्रोफ़ाइल के लिए खास तौर पर बनाया गया हो.
  • Android 7.0 में, ऐसे कई तरीके हैं जो आम तौर पर पूरे डिवाइस पर असर डालते हैं. हालांकि, अगर डिवाइस पर वर्क प्रोफ़ाइल इंस्टॉल है और उसके लिए अलग से वर्क चैलेंज सेट किया गया है, तो ये तरीके अलग तरह से काम करते हैं. ये तरीके पूरे डिवाइस पर असर डालने के बजाय, सिर्फ़ वर्क प्रोफ़ाइल पर लागू होते हैं. (ऐसे तरीकों की पूरी सूची, DevicePolicyManager.getParentProfileInstance() दस्तावेज़ में मौजूद है.) उदाहरण के लिए, DevicePolicyManager.lockNow() पूरे डिवाइस को लॉक करने के बजाय, सिर्फ़ वर्क प्रोफ़ाइल को लॉक करता है. इनमें से हर तरीके के लिए, DevicePolicyManager के पैरंट इंस्टेंस पर तरीके को कॉल करके, पुराना व्यवहार पाया जा सकता है. DevicePolicyManager.getParentProfileInstance() को कॉल करके, यह पैरंट पाया जा सकता है. उदाहरण के लिए, अगर पैरंट इंस्टेंस के lockNow() तरीके को कॉल किया जाता है, तो पूरा डिवाइस लॉक हो जाता है.

एनोटेशन के डेटा का रखरखाव

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

  • VISIBILITY_BUILD: इसे सिर्फ़ बिल्ड के समय दिखने के लिए बनाया गया है.
  • VISIBILITY_SYSTEM: रनटाइम के दौरान दिखने के लिए, लेकिन सिर्फ़ सिस्टम के लिए.

अगर आपका ऐप्लिकेशन इस व्यवहार पर निर्भर है, तो एनोटेशन में एक रिटेंशन नीति जोड़ें. यह नीति रनटाइम के दौरान उपलब्ध होनी चाहिए. इसके लिए, @Retention(RetentionPolicy.RUNTIME) का इस्तेमाल करें.

टीएलएस/एसएसएल के डिफ़ॉल्ट कॉन्फ़िगरेशन में बदलाव

Android 7.0, एचटीटीपीएस और अन्य टीएलएस/एसएसएल ट्रैफ़िक के लिए, ऐप्लिकेशन के इस्तेमाल किए जाने वाले डिफ़ॉल्ट टीएलएस/एसएसएल कॉन्फ़िगरेशन में ये बदलाव करता है:

  • RC4 साइफ़र सुइट अब बंद कर दिए गए हैं.
  • CHACHA20-POLY1305 साइफ़र सुइट अब चालू हैं.

डिफ़ॉल्ट रूप से RC4 के बंद होने पर, एचटीटीपीएस या TLS/एसएसएल कनेक्टिविटी में रुकावटें आ सकती हैं. ऐसा तब होता है, जब सर्वर आधुनिक साइफ़र सुइट के साथ काम नहीं करता. सबसे सही तरीका यह है कि सर्वर के कॉन्फ़िगरेशन को बेहतर बनाया जाए, ताकि ज़्यादा मज़बूत और आधुनिक साइफ़र सुइट और प्रोटोकॉल चालू किए जा सकें. आम तौर पर, TLSv1.2 और AES-GCM चालू होने चाहिए. साथ ही, फ़ॉरवर्ड सीक्रेसी साइफ़र सुइट (ECDHE) चालू होने चाहिए और उन्हें प्राथमिकता दी जानी चाहिए.

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

ध्यान दें: ये बदलाव WebView पर लागू नहीं होते.

Android 7.0 को टारगेट करने वाले ऐप्लिकेशन

काम करने के तरीके में हुए ये बदलाव, सिर्फ़ उन ऐप्लिकेशन पर लागू होते हैं जो Android 7.0 (एपीआई लेवल 24) या इसके बाद के वर्शन को टारगेट करते हैं. Android 7.0 के लिए कंपाइल किए गए ऐप्लिकेशन या targetSdkVersion को Android 7.0 या इसके बाद के वर्शन पर सेट करने वाले ऐप्लिकेशन को अपने ऐप्लिकेशन में बदलाव करना होगा, ताकि वे इन व्यवहारों के साथ ठीक से काम कर सकें. ऐसा वहां करना होगा जहां ऐप्लिकेशन पर लागू हो.

सीरियलाइज़ेशन में बदलाव

Android 7.0 (एपीआई लेवल 24) में, डिफ़ॉल्ट serialVersionUID की कैलकुलेशन में आने वाली गड़बड़ी को ठीक किया गया है. इस गड़बड़ी की वजह से, serialVersionUID की वैल्यू, स्पेसिफ़िकेशन से मैच नहीं होती थी.

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

local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567

इन समस्याओं को ठीक करने के लिए, गड़बड़ी के मैसेज में मौजूद stream classdesc serialVersionUID की वैल्यू के साथ, जिस क्लास पर असर पड़ा है उसमें serialVersionUID फ़ील्ड जोड़ना होगा. उदाहरण के लिए, इस मामले में 1234. यह बदलाव, सीरियलाइज़ेशन कोड लिखने के लिए सुझाई गई सभी अच्छी प्रैक्टिस के मुताबिक है. साथ ही, यह Android के सभी वर्शन पर काम करेगा.

जिस गड़बड़ी को ठीक किया गया था वह स्टैटिक इनिशलाइज़र तरीकों की मौजूदगी से जुड़ी थी, यानी कि <clinit>. स्पेसिफ़िकेशन के मुताबिक, क्लास में स्टैटिक इनिशियलाइज़र मेथड की मौजूदगी या अनुपस्थिति से, उस क्लास के लिए कैलकुलेट किए गए डिफ़ॉल्ट serialVersionUID पर असर पड़ेगा. गड़बड़ी ठीक करने से पहले, अगर किसी क्लास में स्टैटिक इनिशलाइज़र नहीं होता था, तो कैलकुलेशन के दौरान सुपर क्लास में स्टैटिक इनिशलाइज़र की जांच भी की जाती थी.

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

अन्य अहम जानकारी

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

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

    Android 7.0 (एपीआई लेवल 24) और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन, डेंसिटी में बदलाव होने पर अपने-आप बंद नहीं होते. हालांकि, हो सकता है कि कॉन्फ़िगरेशन में बदलाव होने पर वे ठीक से काम न करें.

  • Android 7.0 पर चलने वाले ऐप्लिकेशन, कॉन्फ़िगरेशन में होने वाले बदलावों को आसानी से मैनेज कर सकें. साथ ही, वे बाद में शुरू होने पर क्रैश न हों. फ़ॉन्ट साइज़ बदलकर, ऐप्लिकेशन के काम करने के तरीके की पुष्टि की जा सकती है. इसके लिए, सेटिंग > डिसप्ले > फ़ॉन्ट साइज़ पर जाएं. इसके बाद, हाल ही में इस्तेमाल किए गए ऐप्लिकेशन से ऐप्लिकेशन को वापस लाएं.
  • Android के पिछले वर्शन में मौजूद एक गड़बड़ी की वजह से, सिस्टम ने मुख्य थ्रेड पर टीसीपी सॉकेट में डेटा लिखने को स्ट्रिक्ट मोड के उल्लंघन के तौर पर फ़्लैग नहीं किया. Android 7.0 में इस गड़बड़ी को ठीक कर दिया गया है. इस तरह का व्यवहार करने वाले ऐप्लिकेशन अब android.os.NetworkOnMainThreadException दिखाते हैं. आम तौर पर, मुख्य थ्रेड पर नेटवर्क से जुड़े काम करना सही नहीं होता, क्योंकि इन कामों में ज़्यादा इंतज़ार करना पड़ता है. इससे ANR और जैंक की गड़बड़ियां होती हैं.
  • Debug.startMethodTracing() विधियों का परिवार अब डिफ़ॉल्ट रूप से आउटपुट को एसडी कार्ड के शीर्ष स्तर के बजाय शेयर किया गया स्टोरेज पर आपकी पैकेज-विशिष्ट डायरेक्ट्री में संग्रहीत करता है. इसका मतलब है कि ऐप्लिकेशन को अब इन एपीआई का इस्तेमाल करने के लिए, WRITE_EXTERNAL_STORAGE की अनुमति का अनुरोध करने की ज़रूरत नहीं है.
  • कई प्लैटफ़ॉर्म एपीआई अब Binder लेन-देन के दौरान भेजे जा रहे बड़े पेलोड की जांच करने लगे हैं. साथ ही, सिस्टम अब TransactionTooLargeExceptions को RuntimeExceptions के तौर पर फिर से थ्रो करता है. ऐसा करने के लिए, वह उन्हें चुपचाप लॉग या दबाने के बजाय, फिर से थ्रो करता है. इसका एक आम उदाहरण है, Activity.onSaveInstanceState() में बहुत ज़्यादा डेटा सेव करना. इसकी वजह से, जब आपका ऐप्लिकेशन Android 7.0 को टारगेट करता है, तो ActivityThread.StopInfo, RuntimeException को थ्रो करता है.
  • अगर कोई ऐप्लिकेशन Runnable टास्क को View पर पोस्ट करता है और View किसी विंडो से अटैच नहीं है, तो सिस्टम Runnable टास्क को View के साथ सूची में डाल देता है. Runnable टास्क तब तक पूरा नहीं होता, जब तक View किसी विंडो से अटैच न हो. इस बदलाव से, ये गड़बड़ियां ठीक हो जाती हैं:
    • अगर किसी ऐप्लिकेशन ने तय विंडो के यूज़र इंटरफ़ेस (यूआई) थ्रेड के बजाय, किसी दूसरे थ्रेड से View पर पोस्ट किया है, तो हो सकता है कि Runnable गलत थ्रेड पर चले.
    • अगर Runnable टास्क को लूपर थ्रेड के बजाय किसी अन्य थ्रेड से पोस्ट किया गया था, तो ऐप्लिकेशन Runnable टास्क को एक्सपोज़ कर सकता है.
  • अगर Android 7.0 पर मौजूद कोई ऐप्लिकेशन, DELETE_PACKAGES अनुमति के साथ किसी पैकेज को मिटाने की कोशिश करता है, लेकिन उस पैकेज को किसी दूसरे ऐप्लिकेशन ने इंस्टॉल किया है, तो सिस्टम को उपयोगकर्ता की पुष्टि की ज़रूरत होती है. इस स्थिति में, ऐप्लिकेशन को PackageInstaller.uninstall() को शुरू करने पर, रिटर्न स्टेटस के तौर पर STATUS_PENDING_USER_ACTION की उम्मीद करनी चाहिए.
  • Crypto नाम के जेसीए प्रोवाइडर को अब बंद कर दिया गया है, क्योंकि इसका एकमात्र एल्गोरिदम, SHA1PRNG, क्रिप्टोग्राफ़िक तौर पर कमज़ोर है. ऐप्लिकेशन अब कुंजियों को (असुरक्षित तरीके से) पाने के लिए, SHA1PRNG का इस्तेमाल नहीं कर सकते. ऐसा इसलिए, क्योंकि यह सेवा देने वाली कंपनी अब उपलब्ध नहीं है. ज़्यादा जानकारी के लिए, ब्लॉग पोस्ट Android N में सुरक्षा "क्रिप्टो" प्रोवाइडर को बंद कर दिया गया है देखें.