Android 8.0 (एपीआई लेवल 26) में नई सुविधाओं और क्षमताओं के साथ-साथ, सिस्टम और एपीआई के काम करने के तरीके से जुड़े कई बदलाव शामिल हैं. इस दस्तावेज़ में, कुछ ऐसे अहम बदलावों के बारे में बताया गया है जिन्हें आपको समझना चाहिए और अपने ऐप्लिकेशन में इनका ध्यान रखना चाहिए.
इनमें से ज़्यादातर बदलावों का असर सभी ऐप्लिकेशन पर पड़ता है. भले ही, वे Android के किसी भी वर्शन को टारगेट करते हों. हालांकि, कई बदलावों का असर सिर्फ़ उन ऐप्लिकेशन पर पड़ता है जो Android 8.0 को टारगेट करते हैं. इस पेज को दो सेक्शन में बांटा गया है, ताकि आपको साफ़ तौर पर जानकारी मिल सके: सभी ऐप्लिकेशन के लिए बदलाव और Android 8.0 को टारगेट करने वाले ऐप्लिकेशन के लिए बदलाव.
सभी ऐप्लिकेशन के लिए बदलाव
Android 8.0 (एपीआई लेवल 26) प्लैटफ़ॉर्म पर चलने वाले
ऐप्लिकेशन के बैकग्राउंड में चलने पर नियंत्रण
Android 8.0 (एपीआई लेवल 26) में, बैटरी लाइफ़ को बेहतर बनाने के लिए कई बदलाव किए गए हैं. इनमें से एक बदलाव यह है कि जब आपका ऐप्लिकेशन कैश मेमोरी में सेव हो जाता है और कोई कॉम्पोनेंट चालू नहीं होता, तो सिस्टम ऐप्लिकेशन के सभी वेकलॉक रिलीज़ कर देता है.
साथ ही, डिवाइस की परफ़ॉर्मेंस को बेहतर बनाने के लिए, सिस्टम ऐसे ऐप्लिकेशन की कुछ कार्रवाइयों को सीमित करता है जो फ़ोरग्राउंड में नहीं चल रहे होते. खास तौर से:
- बैकग्राउंड में चल रहे ऐप्लिकेशन के लिए, अब यह तय किया जा सकता है कि वे बैकग्राउंड में चलने वाली सेवाओं को कितनी जल्दी ऐक्सेस कर सकते हैं.
- ऐप्लिकेशन, इंप्लिसिट ब्रॉडकास्ट के लिए रजिस्टर करने के लिए, अपने मेनिफ़ेस्ट का इस्तेमाल नहीं कर सकते. इसका मतलब है कि ऐसे ब्रॉडकास्ट जिन्हें खास तौर पर ऐप्लिकेशन पर टारगेट नहीं किया जाता है.
डिफ़ॉल्ट रूप से, ये पाबंदियां सिर्फ़ उन ऐप्लिकेशन पर लागू होती हैं जो O को टारगेट करते हैं. हालांकि, उपयोगकर्ता सेटिंग स्क्रीन से किसी भी ऐप्लिकेशन के लिए ये पाबंदियां चालू कर सकते हैं. भले ही, ऐप्लिकेशन ने O को टारगेट न किया हो.
Android 8.0 (एपीआई लेवल 26) में, कुछ तरीकों में ये बदलाव भी किए गए हैं:
- अगर Android 8.0 को टारगेट करने वाला कोई ऐप्लिकेशन, बैकग्राउंड में चलने वाली सेवाएं बनाने की अनुमति नहीं देता है, तो
startService()तरीके मेंIllegalStateExceptionतरीके का इस्तेमाल करने की कोशिश की जाती है. Context.startForegroundService()के नए तरीके से फ़ोरग्राउंड सेवा शुरू होती है. सिस्टम, ऐप्लिकेशन कोContext.startForegroundService()को कॉल करने की अनुमति देता है. भले ही, ऐप्लिकेशन बैकग्राउंड में चल रहा हो. हालांकि, सेवा बनने के पांच सेकंड के अंदर, ऐप्लिकेशन को उस सेवा केstartForeground()तरीके को कॉल करना होगा.
ज़्यादा जानकारी के लिए, बैकग्राउंड एक्ज़ीक्यूशन की सीमाएं देखें.
Android पर बैकग्राउंड में जगह की जानकारी ऐक्सेस करने की सीमाएं
बैटरी, उपयोगकर्ता अनुभव, और सिस्टम की परफ़ॉर्मेंस को बेहतर बनाने के लिए, Android 8.0 पर काम करने वाले डिवाइस पर, बैकग्राउंड में काम करने वाले ऐप्लिकेशन को जगह की जानकारी के अपडेट कम मिलते हैं. इस बदलाव का असर उन सभी ऐप्लिकेशन पर पड़ता है जिन्हें जगह की जानकारी के अपडेट मिलते हैं. इनमें Google Play services भी शामिल है.
इन बदलावों का असर इन एपीआई पर पड़ता है:
- कई तरह से जांची गई सही जगह की जानकारी देने वाला एपीआई (एफ़एलपी)
- जियोफ़ेंसिंग
- GNSS मेज़रमेंट
- लोकेशन मैनेजर
- वाई-फ़ाई मैनेजर
यह पक्का करने के लिए कि आपका ऐप्लिकेशन उम्मीद के मुताबिक काम करे, यह तरीका अपनाएं:
- अपने ऐप्लिकेशन के लॉजिक की समीक्षा करें और पक्का करें कि आपने जगह की जानकारी के लिए, सबसे नए एपीआई का इस्तेमाल किया हो.
- जांच लें कि आपका ऐप्लिकेशन, इस्तेमाल के हर उदाहरण के लिए ठीक वैसा ही व्यवहार दिखा रहा है जिसकी उम्मीद आपको है.
- उपयोगकर्ता की मौजूदा जगह के आधार पर काम करने वाले उदाहरणों को मैनेज करने के लिए, फ़्यूज़्ड लोकेशन प्रोवाइडर (एफ़एलपी) या जियोफ़ेंसिंग का इस्तेमाल करें.
इन बदलावों के बारे में ज़्यादा जानकारी के लिए, बैकग्राउंड में जगह की जानकारी ऐक्सेस करने की सीमाएं देखें.
ऐप शॉर्टकट
Android 8.0 (एपीआई लेवल 26) में ऐप्लिकेशन शॉर्टकट के लिए किए गए ये बदलाव शामिल हैं:
com.android.launcher.action.INSTALL_SHORTCUTब्रॉडकास्ट का अब आपके ऐप्लिकेशन पर कोई असर नहीं पड़ेगा, क्योंकि अब यह एक निजी और गुप्त ब्रॉडकास्ट है. इसके बजाय, आपकोShortcutManagerक्लास केrequestPinShortcut()तरीके का इस्तेमाल करके, ऐप्लिकेशन का शॉर्टकट बनाना चाहिए.ACTION_CREATE_SHORTCUTइंटेंट अब ऐप्लिकेशन के शॉर्टकट बना सकता है. इन्हेंShortcutManagerक्लास का इस्तेमाल करके मैनेज किया जा सकता है. यह इंटेंट, ऐसे लेगसी लॉन्चर शॉर्टकट भी बना सकता है जोShortcutManagerके साथ इंटरैक्ट नहीं करते. पहले, इस इंटेंट से सिर्फ़ लेगसी लॉन्चर के शॉर्टकट बनाए जा सकते थे.requestPinShortcut()का इस्तेमाल करके बनाए गए शॉर्टकट औरACTION_CREATE_SHORTCUTइंटेंट को मैनेज करने वाली गतिविधि में बनाए गए शॉर्टकट अब पूरी तरह से ऐप्लिकेशन शॉर्टकट हैं. इसलिए, ऐप्लिकेशन अबShortcutManagerमें दिए गए तरीकों का इस्तेमाल करके, उन्हें अपडेट कर सकते हैं.- लेगसी शॉर्टकट, Android के पिछले वर्शन में मौजूद अपनी सुविधाओं को बनाए रखते हैं. हालांकि, आपको अपने ऐप्लिकेशन में उन्हें मैन्युअल रूप से ऐप्लिकेशन शॉर्टकट में बदलना होगा.
ऐप शॉर्टकट में किए गए बदलावों के बारे में ज़्यादा जानने के लिए, शॉर्टकट और विजेट पिन करना सुविधा गाइड देखें.
स्थानीय भाषा और अंतरराष्ट्रीय भाषा
Android 7.0 (एपीआई लेवल 24) में, डिफ़ॉल्ट कैटगरी भाषा तय करने की सुविधा जोड़ी गई थी. हालांकि, कुछ एपीआई ने बिना किसी आर्ग्युमेंट के, सामान्य Locale.getDefault()
तरीके का इस्तेमाल करना जारी रखा. इसके बजाय, उन्हें डिफ़ॉल्ट DISPLAY कैटगरी भाषा का इस्तेमाल करना चाहिए था. Android 8.0 (एपीआई लेवल 26) में,
अब ये तरीके Locale.getDefault() के बजाय
Locale.getDefault(Category.DISPLAY) का इस्तेमाल करते हैं:
Locale आर्ग्युमेंट के लिए बताई गई displayScript वैल्यू उपलब्ध न होने पर, Locale.getDisplayScript(Locale) भी Locale.getDefault() पर वापस आ जाता है.
स्थान-भाषा और अंतरराष्ट्रीय मानकों के मुताबिक, यहां बताए गए बदलाव किए गए हैं:
Currency.getDisplayName(null)को कॉल करने पर, एकNullPointerExceptionदिखता है. यह दस्तावेज़ में दिए गए व्यवहार से मेल खाता है.- टाइम ज़ोन के नाम को पार्स करने का तरीका बदल गया है. पहले,
Android डिवाइसों में, टाइम ज़ोन के नामों को कैश मेमोरी में सेव करने के लिए, सिस्टम घड़ी की वैल्यू का इस्तेमाल किया जाता था. यह वैल्यू, डिवाइस के चालू होने के समय सैंपल की जाती थी. इन नामों का इस्तेमाल, तारीख और समय को पार्स करने के लिए किया जाता था. इस वजह से, अगर बूट के समय सिस्टम की घड़ी गलत थी या कुछ और ऐसे मामले थे, तो पार्स करने की प्रोसेस पर बुरा असर पड़ सकता था.
अब, आम तौर पर टाइम ज़ोन के नामों को पार्स करते समय, पार्स करने का लॉजिक, ICU और मौजूदा सिस्टम क्लॉक की वैल्यू का इस्तेमाल करता है. इस बदलाव की वजह से, ज़्यादा सटीक नतीजे मिलते हैं. अगर आपका ऐप्लिकेशन
SimpleDateFormatजैसी क्लास का इस्तेमाल करता है, तो ये नतीजे Android के पुराने वर्शन से अलग हो सकते हैं. - Android 8.0 (एपीआई लेवल 26) में, ICU का वर्शन 58 पर अपडेट किया गया है.
अलर्ट विंडो
अगर कोई ऐप्लिकेशन SYSTEM_ALERT_WINDOW अनुमति का इस्तेमाल करता है और दूसरे ऐप्लिकेशन और सिस्टम विंडो के ऊपर चेतावनी विंडो दिखाने के लिए, इनमें से किसी एक तरह की विंडो का इस्तेमाल करता है, तो:
...तो ये विंडो हमेशा उन विंडो के नीचे दिखती हैं जिनमें TYPE_APPLICATION_OVERLAY विंडो टाइप का इस्तेमाल किया जाता है. अगर कोई ऐप्लिकेशन Android 8.0 (एपीआई लेवल 26) को टारगेट करता है, तो वह सूचना वाली विंडो दिखाने के लिए, TYPE_APPLICATION_OVERLAY
विंडो टाइप का इस्तेमाल करता है.
ज़्यादा जानकारी के लिए, Android 8.0 को टारगेट करने वाले ऐप्लिकेशन के लिए, व्यवहार में हुए बदलावों में सूचना विंडो के लिए सामान्य विंडो टाइप सेक्शन देखें.
इनपुट और नेविगेशन
ChromeOS और टैबलेट जैसे बड़े फ़ॉर्म फ़ैक्टर पर Android ऐप्लिकेशन के आने के बाद, हमें Android ऐप्लिकेशन में कीबोर्ड नेविगेशन के इस्तेमाल में फिर से बढ़ोतरी दिख रही है. Android 8.0 (एपीआई लेवल 26) में, हमने नेविगेशन इनपुट डिवाइस के तौर पर कीबोर्ड का इस्तेमाल करने की सुविधा को फिर से अपडेट किया है. इससे ऐरो और टैब पर आधारित नेविगेशन के लिए, ज़्यादा भरोसेमंद और अनुमान लगाने लायक मॉडल तैयार हुआ है.
खास तौर पर, हमने एलिमेंट के फ़ोकस व्यवहार में ये बदलाव किए हैं:
-
अगर आपने
Viewऑब्जेक्ट (उसके फ़ोरग्राउंड या बैकग्राउंड ड्रॉ करने लायक) के लिए, फ़ोकस की स्थिति का कोई रंग तय नहीं किया है, तो फ़्रेमवर्क अबViewके लिए, फ़ोकस हाइलाइट करने के लिए डिफ़ॉल्ट रंग सेट करता है. यह फ़ोकस हाइलाइट, गतिविधि की थीम के आधार पर, डूडल के तौर पर दिखने वाली एक लहर होती है.अगर आपको किसी
Viewऑब्जेक्ट पर फ़ोकस होने पर, इस डिफ़ॉल्ट हाइलाइट का इस्तेमाल नहीं करना है, तोViewवाली लेआउट एक्सएमएल फ़ाइल मेंandroid:defaultFocusHighlightEnabledएट्रिब्यूट कोfalseपर सेट करें या अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) लॉजिक मेंfalseकोsetDefaultFocusHighlightEnabled()पर पास करें. - कीबोर्ड इनपुट, यूज़र इंटरफ़ेस (यूआई) एलिमेंट के फ़ोकस पर कैसे असर डालता है, इसकी जांच करने के लिए डेवलपर के लिए, ड्रॉइंग > लेआउट की सीमाएं दिखाएं डेवलपर विकल्प को चालू करें. Android 8.0 में, यह विकल्प उस एलिमेंट के ऊपर "X" आइकॉन दिखाता है जिस पर फ़िलहाल फ़ोकस है.
साथ ही, Android 8.0 में टूलबार के सभी एलिमेंट, कीबोर्ड नेविगेशन क्लस्टर के तौर पर अपने-आप काम करते हैं. इससे, उपयोगकर्ताओं के लिए हर टूलबार में नेविगेट करना और उससे बाहर निकलना आसान हो जाता है.
अपने ऐप्लिकेशन में कीबोर्ड नेविगेशन की सुविधा को बेहतर बनाने के तरीके के बारे में ज़्यादा जानने के लिए, कीबोर्ड नेविगेशन की सुविधा इस्तेमाल करने के बारे में जानकारी वाली गाइड पढ़ें.
अपने-आप फ़ॉर्म भरने की सुविधा के लिए वेब फ़ॉर्म
Android ऑटोमैटिक भरने की सुविधा का फ़्रेमवर्क, अब ऑटोमैटिक भरने की सुविधा के लिए पहले से मौजूद सहायता देता है. इसलिए, Android 8.0 (एपीआई लेवल 26) पर चलने वाले डिवाइसों पर इंस्टॉल किए गए ऐप्लिकेशन के लिए, WebView ऑब्जेक्ट से जुड़े ये तरीके बदल गए हैं:
WebSettings-
getSaveFormData()तरीका, अबfalseदिखाता है. पहले, इस तरीके से नतीजे के तौर परtrueका इस्तेमाल किया जाता था.setSaveFormData()को कॉल करने का अब कोई असर नहीं पड़ता.
WebViewDatabase-
clearFormData()को कॉल करने का अब कोई असर नहीं पड़ता.- अब
hasFormData()तरीके से,falseमिलता है. पहले, इस तरीके में डेटा होने परtrueदिखता था.
सुलभता
Android 8.0 (एपीआई लेवल 26) में, सुलभता से जुड़े ये बदलाव किए गए हैं:
-
सुलभता फ़्रेमवर्क अब सभी दो बार टैप करने के जेस्चर को
ACTION_CLICKऐक्शन में बदल देता है. इस बदलाव की मदद से, TalkBack की सुविधा अन्य सुलभता सेवाओं की तरह ही काम करती है.अगर आपके ऐप्लिकेशन के
Viewऑब्जेक्ट, मैन्युअल तरीके से टच हैंडलिंग का इस्तेमाल करते हैं, तो आपको इस बात की पुष्टि करनी होगी कि वे अब भी TalkBack के साथ काम कर रहे हैं. आपको सिर्फ़ उस क्लिक हैंडलर को रजिस्टर करना पड़ सकता है जिसका इस्तेमाल आपकेViewऑब्जेक्ट करते हैं. अगर TalkBack अब भी इनViewऑब्जेक्ट पर किए गए जेस्चर को नहीं पहचानता है, तोperformAccessibilityAction()को बदलें. - सुलभता सेवाओं को अब आपके ऐप्लिकेशन के
TextViewऑब्जेक्ट में मौजूद सभीClickableSpanइंस्टेंस के बारे में पता है.
अपने ऐप्लिकेशन को ज़्यादा से ज़्यादा लोगों तक पहुंचाने के बारे में ज़्यादा जानने के लिए, सुलभता लेख पढ़ें.
नेटवर्किंग और एचटीटीपी या एचटीटीपीएस कनेक्टिविटी
Android 8.0 (एपीआई लेवल 26) में, नेटवर्क और एचटीटीपी(एस) कनेक्टिविटी के काम करने के तरीके में ये बदलाव किए गए हैं:
- बिना मुख्य हिस्से वाले OPTIONS अनुरोधों में
Content-Length: 0हेडर होता है. पहले उनके पासContent-Lengthहेडर नहीं था. - HttpURLConnection, होस्ट या अथॉरिटी के नाम के बाद स्लैश जोड़कर, खाली पाथ वाले यूआरएल को सामान्य बनाता है. उदाहरण के लिए, यह
http://example.comकोhttp://example.com/में बदल देता है. - ProxySelector.setDefault() के ज़रिए सेट किया गया कस्टम प्रॉक्सी सिलेक्टर, सिर्फ़ अनुरोध किए गए यूआरएल के पते (स्कीम, होस्ट, और पोर्ट) को टारगेट करता है. इसलिए, प्रॉक्सी का विकल्प सिर्फ़ उन वैल्यू के आधार पर चुना जा सकता है. कस्टम प्रॉक्सी सिलेक्टर को भेजे गए यूआरएल में, अनुरोध किए गए यूआरएल का पाथ, क्वेरी पैरामीटर या फ़्रैगमेंट शामिल नहीं होता.
- यूआरआई में खाली लेबल नहीं हो सकते.
पहले, प्लैटफ़ॉर्म पर होस्ट नेम में खाली लेबल स्वीकार करने के लिए, एक तरीका अपनाया जाता था. यह यूआरआई का गैर-कानूनी इस्तेमाल है. यह तरीका, libcore के पुराने रिलीज़ के साथ काम करने के लिए था. एपीआई का गलत तरीके से इस्तेमाल करने वाले डेवलपर को एडीबी का यह मैसेज दिखेगा: "यूआरआई example..com के होस्टनेम में खाली लेबल हैं. यह गलत है और इसे Android के आने वाले वर्शन में स्वीकार नहीं किया जाएगा." Android 8.0 में, इस तरीके को हटा दिया गया है. सिस्टम, गलत यूआरआई के लिए, वैल्यू के तौर पर 'शून्य' दिखाता है.
- Android 8.0 में HttpsURLConnection को लागू करने पर, असुरक्षित TLS/SSL प्रोटोकॉल वर्शन फ़ॉलबैक नहीं होता.
- टनलिंग एचटीटीपी(एस) कनेक्शन के इस्तेमाल में ये बदलाव किए गए हैं:
- कनेक्शन पर एचटीटीपीएस कनेक्शन को टनल करते समय, सिस्टम, होस्ट लाइन में पोर्ट नंबर (:443) को सही तरीके से डालता है. ऐसा तब किया जाता है, जब यह जानकारी किसी इंटरमीडियरी सर्वर को भेजी जाती है. पहले, पोर्ट नंबर सिर्फ़ CONNECT लाइन में दिखता था.
- सिस्टम अब टनल किए गए अनुरोध से, प्रॉक्सी सर्वर पर उपयोगकर्ता-एजेंट और प्रॉक्सी-अनुमति
हेडर नहीं भेजता.
टनल सेट अप करते समय, सिस्टम अब प्रॉक्सी को टनल किए गए Http(s)URLConnection पर, प्रॉक्सी-अनुमति हेडर नहीं भेजता. इसके बजाय, सिस्टम एक प्रॉक्सी-अनुमति हेडर जनरेट करता है और उसे प्रॉक्सी को भेजता है. ऐसा तब होता है, जब प्रॉक्सी, शुरुआती अनुरोध के जवाब में एचटीटीपी 407 भेजता है.
इसी तरह, सिस्टम अब टनल किए गए अनुरोध से उपयोगकर्ता-एजेंट हेडर को कॉपी नहीं करता है. यह हेडर, टनल सेट अप करने वाले प्रॉक्सी अनुरोध में कॉपी किया जाता है. इसके बजाय, लाइब्रेरी उस अनुरोध के लिए उपयोगकर्ता-एजेंट हेडर जनरेट करती है.
- अगर पहले चलाया गया Connect()
तरीका काम नहीं कर रहा है, तो
send(java.net.DatagramPacket)तरीके से Socketअपवाद देता है.- अगर कोई इंटरनल गड़बड़ी होती है, तो DatagramSocket.connect() एक pendingSocketException सेट करता है. Android 8.0 से पहले, recv() के बाद का कॉल करने पर SocketException का मैसेज मिलता था. भले ही, send() कॉल काम कर गया हो. एक जैसी स्थिति के लिए, अब दोनों कॉल में SocketException दिखता है.
- InetAddress.isReachable() पहले ICMP की कोशिश करता है और फिर TCP Echo प्रोटोकॉल का इस्तेमाल करता है.
- अगर ICMP Echo प्रोटोकॉल स्वीकार करने वाले होस्ट, पोर्ट 7 (TCP Echo) को ब्लॉक करते हैं, तो हो सकता है कि अब उन तक पहुंचा जा सके. जैसे, google.com.
- जिन होस्ट तक कॉल नहीं पहुंच पाता उनके लिए, इस बदलाव का मतलब है कि कॉल वापस आने में दोगुना समय लगेगा.
ब्लूटूथ
Android 8.0 (एपीआई लेवल 26) में, ScanRecord.getBytes()
तरीके से वापस पाए जाने वाले डेटा की लंबाई में ये बदलाव किए गए हैं:
getBytes()तरीका, मिले बाइट की संख्या के बारे में कोई अनुमान नहीं लगाता. इसलिए, ऐप्लिकेशन को लौटाए गए किसी भी कम से कम या ज़्यादा से ज़्यादा बाइट पर भरोसा नहीं करना चाहिए. इसके बजाय, उन्हें नतीजे के तौर पर बने कलेक्शन की लंबाई का आकलन करना चाहिए.- ब्लूटूथ 5 के साथ काम करने वाले डिवाइसों में, डेटा की लंबाई ~60 बाइट तक की हो सकती है.
- अगर कोई रिमोट डिवाइस स्कैन का जवाब नहीं देता है, तो 60 बाइट से कम डेटा भी दिख सकता है.
आसान कनेक्टिविटी
Android 8.0 (एपीआई लेवल 26) की मदद से, वाई-फ़ाई सेटिंग में कई सुधार किए गए हैं. इससे, लोगों को बेहतरीन अनुभव देने वाले वाई-फ़ाई नेटवर्क को चुनना आसान हो जाता है. इनमें ये बदलाव शामिल हैं:
- ऐप्लिकेशन क्रैश या हैंग होने से बचाने के लिए किए गए सुधार.
- आसानी से पढ़ा जा सकने वाला यूज़र इंटरफ़ेस (यूआई).
- एक ही जगह पर सभी के लिए एक ही जगह पर वाई-फ़ाई की प्राथमिकताओं का मेन्यू.
- अच्छी क्वालिटी का सेव किया गया नेटवर्क आस-पास होने पर, काम करने वाले डिवाइसों पर वाई-फ़ाई अपने-आप चालू होना.
सुरक्षा
Android 8.0 में सुरक्षा से जुड़े ये बदलाव किए गए हैं:
- यह प्लैटफ़ॉर्म अब SSLv3 के साथ काम नहीं करता.
- अगर किसी ऐसे सर्वर से एचटीटीपीएस कनेक्शन बनाया जा रहा है जो TLS प्रोटोकॉल के वर्शन के लिए बातचीत करने की सुविधा को गलत तरीके से लागू करता है, तो
HttpsURLConnection, TLS प्रोटोकॉल के पुराने वर्शन पर वापस जाकर फिर से कोशिश करने की कोशिश नहीं करता. - Android 8.0 (एपीआई लेवल 26), सभी ऐप्लिकेशन पर सुरक्षित कंप्यूटिंग (SECCOMP) वाला फ़िल्टर लागू करता है. अनुमति वाले सिस्टम कॉल की सूची सिर्फ़ बायोनिक के ज़रिए दिखाए जाने वाले सिस्टम के लिए है. हालांकि, पुराने सिस्टम के साथ काम करने की सुविधा के लिए कई अन्य सिस्टम कॉल उपलब्ध हैं, लेकिन हमारा सुझाव है कि इनका इस्तेमाल न करें.
- आपके ऐप्लिकेशन के
WebViewऑब्जेक्ट अब मल्टीप्रोसेस मोड में चलते हैं. बेहतर सुरक्षा के लिए, वेब कॉन्टेंट को ऐप्लिकेशन की प्रोसेस से अलग, अलग से मैनेज किया जाता है. -
अब यह नहीं माना जा सकता कि APK उन डायरेक्ट्री में मौजूद होते हैं जिनके नाम -1 या -2 पर खत्म होते हैं. ऐप्लिकेशन को डायरेक्ट्री पाने के लिए,
sourceDirका इस्तेमाल करना चाहिए. साथ ही, डायरेक्ट्री फ़ॉर्मैट पर सीधे तौर पर भरोसा नहीं करना चाहिए. - नेटिव लाइब्रेरी के इस्तेमाल से जुड़ी सुरक्षा को बेहतर बनाने के बारे में जानकारी पाने के लिए, नेटिव लाइब्रेरी देखें.
इसके अलावा, Android 8.0 (एपीआई लेवल 26) में, अनजान सोर्स से ऐप्लिकेशन इंस्टॉल करने से जुड़े ये बदलाव किए गए हैं:
- लेगसी सेटिंग
INSTALL_NON_MARKET_APPSकी वैल्यू अब हमेशा 1 होती है. यह तय करने के लिए कि कोई अनजान सोर्स, पैकेज इंस्टॉलर का इस्तेमाल करके ऐप्लिकेशन इंस्टॉल कर सकता है या नहीं, आपकोcanRequestPackageInstalls()की रिटर्न वैल्यू का इस्तेमाल करना चाहिए. setSecureSetting()का इस्तेमाल करकेINSTALL_NON_MARKET_APPSकी वैल्यू बदलने की कोशिश करने पर, एकUnsupportedOperationExceptionदिखता है. उपयोगकर्ताओं को अज्ञात सोर्स का इस्तेमाल करके, अनजान ऐप्लिकेशन इंस्टॉल करने से रोकने के लिए, उपयोगकर्ता परDISALLOW_INSTALL_UNKNOWN_SOURCESपाबंदी लागू करनी चाहिए.-
Android 8.0 (एपीआई लेवल 26) वाले डिवाइसों पर बनाई गई मैनेज की जा सकने वाली प्रोफ़ाइलों में,
DISALLOW_INSTALL_UNKNOWN_SOURCESउपयोगकर्ता पर पाबंदी अपने-आप लागू हो जाती है. Android 8.0 में अपग्रेड किए गए डिवाइस पर मैनेज की जा रही मौजूदा प्रोफ़ाइलों के लिए,DISALLOW_INSTALL_UNKNOWN_SOURCESउपयोगकर्ता से जुड़ी पाबंदी अपने-आप चालू हो जाती है. अगर प्रोफ़ाइल के मालिक नेINSTALL_NON_MARKET_APPSको 1 पर सेट करके, इस पाबंदी को (अपग्रेड करने से पहले) साफ़ तौर पर बंद नहीं किया है, तो पाबंदी लागू नहीं होगी.
अनजान ऐप्लिकेशन इंस्टॉल करने के बारे में ज़्यादा जानकारी के लिए, अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमतियां गाइड देखें.
अपने ऐप्लिकेशन को ज़्यादा सुरक्षित बनाने के बारे में ज़्यादा दिशा-निर्देश पाने के लिए, Android डेवलपर के लिए सुरक्षा देखें.
निजता
Android 8.0 (एपीआई लेवल 26) में, प्लैटफ़ॉर्म पर निजता से जुड़े ये बदलाव किए गए हैं.
- अब प्लैटफ़ॉर्म, आइडेंटिफ़ायर को अलग तरीके से मैनेज करता है.
-
ऐसे ऐप्लिकेशन के लिए जिनके लिए, ओटीए के ज़रिए Android 8.0 (एपीआई लेवल 26) (एपीआई लेवल 26) के वर्शन पर अपग्रेड करने से पहले इंस्टॉल किया गया था,
ANDROID_IDकी वैल्यू तब तक एक जैसी रहती है, जब तक कि ओटीए के बाद ऐप्लिकेशन को अनइंस्टॉल करके फिर से इंस्टॉल नहीं किया जाता. ओटीए के बाद, डिवाइस को अनइंस्टॉल करने पर भी वैल्यू को सेव रखने के लिए, डेवलपर की/वैल्यू के बैकअप का इस्तेमाल करके, पुरानी और नई वैल्यू को जोड़ सकते हैं. - Android 8.0 वाले डिवाइस पर इंस्टॉल किए गए ऐप्लिकेशन के लिए,
ANDROID_IDकी वैल्यू अब हर ऐप्लिकेशन साइनिंग पासकोड के साथ-साथ हर उपयोगकर्ता के लिए तय की गई है. ऐप्लिकेशन साइनिंग पासकोड, उपयोगकर्ता, और डिवाइस के हर कॉम्बिनेशन के लिए,ANDROID_IDकी वैल्यू यूनीक होती है. इस वजह से, एक ही डिवाइस पर अलग-अलग साइनिंग पासकोड वाले ऐप्लिकेशन को अब एक ही Android आईडी नहीं दिखता. भले ही, वह ऐप्लिकेशन किसी एक ही उपयोगकर्ता के लिए हो. - पैकेज को अनइंस्टॉल करने या फिर से इंस्टॉल करने पर,
ANDROID_IDकी वैल्यू नहीं बदलती है. हालांकि, ऐसा तब होता है, जब साइनिंग पासकोड में कोई बदलाव न किया गया हो. साथ ही, अगर ऐप्लिकेशन को ओटीए से पहले Android 8.0 वाले वर्शन पर इंस्टॉल न किया गया हो. ANDROID_IDकी वैल्यू में कोई बदलाव नहीं होता, भले ही सिस्टम अपडेट की वजह से पैकेज साइन करने की कुंजी बदल जाए.- Google Play services और विज्ञापन आईडी के साथ शिप होने वाले डिवाइसों पर, आपको
विज्ञापन आईडी का इस्तेमाल करना होगा. ऐप्लिकेशन से कमाई करने के लिए आसान और स्टैंडर्ड सिस्टम,
विज्ञापन आईडी, विज्ञापन के लिए इस्तेमाल किया जाने वाला यूनीक आईडी है. इसे उपयोगकर्ता अपने हिसाब से सेट कर सकता है. इसे Google Play services उपलब्ध कराता है.
डिवाइस बनाने वाली अन्य कंपनियों को
ANDROID_IDउपलब्ध कराना जारी रखना चाहिए.
-
ऐसे ऐप्लिकेशन के लिए जिनके लिए, ओटीए के ज़रिए Android 8.0 (एपीआई लेवल 26) (एपीआई लेवल 26) के वर्शन पर अपग्रेड करने से पहले इंस्टॉल किया गया था,
net.hostnameसिस्टम प्रॉपर्टी को क्वेरी करने से, शून्य नतीजे मिलता है.
उन अपवादों की जानकारी भी लॉग करना जिनकी पहचान नहीं हुई है
अगर कोई ऐप्लिकेशन ऐसा Thread.UncaughtExceptionHandler इंस्टॉल करता है जो डिफ़ॉल्ट Thread.UncaughtExceptionHandler को कॉल नहीं करता है, तो सिस्टम किसी अपवाद का पता चलने पर ऐप्लिकेशन को बंद नहीं करता. Android 8.0 (एपीआई लेवल 26) से, सिस्टम इस स्थिति में अपवाद स्टैकट्रैक को लॉग करता है. प्लैटफ़ॉर्म के पुराने वर्शन में, सिस्टम अपवाद स्टैकट्रैक को लॉग नहीं करता था.
हमारा सुझाव है कि कस्टम Thread.UncaughtExceptionHandler लागू करने की सुविधा को हमेशा डिफ़ॉल्ट हैंडलर के ज़रिए कॉल किया जाए; इस सुझाव का पालन करने वाले ऐप्लिकेशन पर Android 8.0 में हुए बदलाव का कोई असर नहीं होता है.
findViewById() हस्ताक्षर में बदलाव
findViewById() तरीके के सभी इंस्टेंस अब View के बजाय
<T extends View> T दिखाते हैं. इस बदलाव
के ये नतीजे होंगे:
- इस वजह से, मौजूदा कोड में रिटर्न टाइप अब अस्पष्ट हो सकता है. उदाहरण के लिए, अगर
someMethod(View)औरsomeMethod(TextView), दोनों ऐसे हैं जोfindViewById()को कॉल करने का नतीजा देते हैं. - Java 8 सोर्स लैंग्वेज का इस्तेमाल करते समय, रिटर्न टाइप के बिना किसी पाबंदी के (उदाहरण के लिए,
assertNotNull(findViewById(...)).someViewMethod())) होने पर, इसेViewमें साफ़ तौर पर कास्ट करना ज़रूरी है. findViewById()के ऐसे तरीकों (उदाहरण के लिए,Activity.findViewById()) को बदलने पर जिनका इस्तेमाल फ़ाइनल रिज़ल्ट के लिए नहीं किया जाता, उनके रिटर्न टाइप को अपडेट करना होगा.
संपर्कों की जानकारी देने वाली सेवा के इस्तेमाल के आंकड़े बदलना
Android के पिछले वर्शन में, Contacts Provider कॉम्पोनेंट की मदद से, डेवलपर हर संपर्क के इस्तेमाल का डेटा पा सकते हैं. इस्तेमाल से जुड़ा यह डेटा, किसी संपर्क से जुड़े हर ईमेल पते और हर फ़ोन नंबर की जानकारी दिखाता है. इसमें, संपर्क किए जाने की संख्या और आखिरी बार संपर्क किए जाने की तारीख भी शामिल है. READ_CONTACTS अनुमति का अनुरोध करने वाले ऐप्लिकेशन, इस डेटा को पढ़ सकते हैं.
ऐप्लिकेशन अब भी इस डेटा को पढ़ सकते हैं. इसके लिए, उन्हें
READ_CONTACTS
की अनुमति का अनुरोध करना होगा. Android 8.0 (एपीआई लेवल 26) और उसके बाद के वर्शन में, इस्तेमाल के डेटा के लिए की गई क्वेरी से सटीक वैल्यू के बजाय, अनुमानित वैल्यू मिलती हैं. Android सिस्टम, अंदरूनी तौर पर
सटीक वैल्यू को बनाए रखता है. इसलिए, इस बदलाव का असर
अपने-आप पूरा होने वाले एपीआई पर नहीं पड़ता.
इस बदलाव से इन क्वेरी पैरामीटर पर असर पड़ता है:
कलेक्शन मैनेज करना
AbstractCollection.removeAll() और AbstractCollection.retainAll() अब हमेशा NullPointerException दिखाते हैं. पहले, कलेक्शन खाली होने पर NullPointerException नहीं दिखाया जाता था. इस बदलाव से, दस्तावेज़ में बताए गए तरीके के मुताबिक काम किया जा सकेगा.
Android Enterprise
Android 8.0 (एपीआई लेवल 26) में, एंटरप्राइज़ ऐप्लिकेशन के लिए कुछ एपीआई और सुविधाओं के काम करने के तरीके में बदलाव किया गया है. इनमें डिवाइस नीति कंट्रोल करने वाले (डीपीसी) भी शामिल हैं. इन बदलावों में ये शामिल हैं:
- पूरी तरह से मैनेज किए जा रहे डिवाइसों पर, ऐप्लिकेशन को वर्क प्रोफ़ाइल के साथ काम करने में मदद करने के लिए नई सुविधाएं.
- डिवाइस और सिस्टम की सुरक्षा को बेहतर बनाने के लिए, सिस्टम अपडेट मैनेज करने, ऐप्लिकेशन की पुष्टि करने, और पुष्टि करने की प्रोसेस में बदलाव किए गए हैं.
- प्रावधान करने, सूचनाओं, हाल ही के स्क्रीन, और हमेशा चालू रहने वाले वीपीएन के लिए उपयोगकर्ता अनुभव में सुधार.
Android 8.0 (एपीआई लेवल 26) में किए गए सभी एंटरप्राइज़ बदलावों को देखने और यह जानने के लिए कि इनसे आपके ऐप्लिकेशन पर क्या असर पड़ सकता है, एंटरप्राइज़ के लिए Android लेख पढ़ें.
Android 8.0 को टारगेट करने वाले ऐप्लिकेशन
ऐप्लिकेशन के काम करने के तरीके में ये बदलाव, सिर्फ़ उन ऐप्लिकेशन पर लागू होंगे जो
Android 8.0 (एपीआई लेवल 26) या उसके बाद के वर्शन को टारगेट कर रहे हैं. Android 8.0 के लिए कॉम्पाइल किए गए ऐप्लिकेशन या targetSdkVersion को Android 8.0 या उसके बाद के वर्शन पर सेट करने वाले ऐप्लिकेशन को, अपने ऐप्लिकेशन में बदलाव करना होगा, ताकि ये ऐप्लिकेशन इन बदलावों के साथ सही तरीके से काम कर सकें. हालांकि, ऐसा सिर्फ़ उन ऐप्लिकेशन के लिए ज़रूरी है जिन पर ये बदलाव लागू होते हैं.
अलर्ट विंडो
SYSTEM_ALERT_WINDOW अनुमति का इस्तेमाल करने वाले ऐप्लिकेशन, अब दूसरे ऐप्लिकेशन और सिस्टम विंडो के ऊपर अलर्ट विंडो दिखाने के लिए, यहां दी गई विंडो टाइप का इस्तेमाल नहीं कर सकते:
इसके बजाय, ऐप्लिकेशन को TYPE_APPLICATION_OVERLAY नाम की नई विंडो का इस्तेमाल करना चाहिए.
अपने ऐप्लिकेशन के लिए सूचना वाली विंडो दिखाने के लिए, TYPE_APPLICATION_OVERLAY विंडो टाइप का इस्तेमाल करते समय, नई विंडो टाइप की इन विशेषताओं को ध्यान में रखें:
- ऐप्लिकेशन की सूचना वाली विंडो हमेशा ज़रूरी सिस्टम विंडो के नीचे दिखती हैं. जैसे, स्टेटस बार और आईएमई.
- स्क्रीन पर कॉन्टेंट को बेहतर तरीके से दिखाने के लिए, सिस्टम उन विंडो को एक जगह से दूसरी जगह ले जा सकता है या उनका साइज़ बदल सकता है जिनमें
TYPE_APPLICATION_OVERLAYविंडो टाइप का इस्तेमाल किया गया है. - सूचना शेड खोलकर, उपयोगकर्ता किसी ऐप्लिकेशन को
TYPE_APPLICATION_OVERLAYविंडो टाइप का इस्तेमाल करके दिखाई जाने वाली सूचना विंडो दिखाने से रोकने के लिए, सेटिंग ऐक्सेस कर सकते हैं.
कॉन्टेंट में बदलाव होने की सूचनाएं
Android 8.0 (एपीआई लेवल 26) में, Android 8.0 को टारगेट करने वाले ऐप्लिकेशन के लिए, ContentResolver.notifyChange() और registerContentObserver(Uri, boolean, ContentObserver) के काम करने के तरीके में बदलाव किया गया है.
इन एपीआई के लिए अब यह ज़रूरी है कि सभी Uris में अथॉरिटी के लिए एक मान्य ContentProvider तय किया गया हो. काम की अनुमतियों के साथ मान्य ContentProvider तय करने से, आपके ऐप्लिकेशन को नुकसान पहुंचाने वाले ऐप्लिकेशन से कॉन्टेंट में होने वाले बदलावों से बचाने में मदद मिलेगी. साथ ही, आपको नुकसान पहुंचाने वाले ऐप्लिकेशन को संभावित निजी डेटा लीक होने से भी बचाया जा सकेगा.
फ़ोकस देखना
क्लिक किए जा सकने वाले View ऑब्जेक्ट अब डिफ़ॉल्ट रूप से फ़ोकस किए जा सकते हैं. अगर आपको किसी View ऑब्जेक्ट को क्लिक किया जा सकने वाला, लेकिन फ़ोकस न किया जा सकने वाला बनाना है, तो View वाली लेआउट एक्सएमएल फ़ाइल में,
android:focusable एट्रिब्यूट को false पर सेट करें. इसके अलावा, अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) लॉजिक में false को setFocusable() पर पास करें.
ब्राउज़र की पहचान करने वाली सुविधा में उपयोगकर्ता-एजेंट मैच
Android 8.0 (एपीआई लेवल 26) और उसके बाद के वर्शन में, बिल्ड आइडेंटिफ़ायर स्ट्रिंग OPR शामिल होती है. कुछ पैटर्न मैच की वजह से, ब्राउज़र का पता लगाने वाले लॉजिक की गड़बड़ी की वजह से, Opera के अलावा किसी दूसरे ब्राउज़र को Opera के तौर पर गलत तरीके से पहचाना जा सकता है.
ऐसे पैटर्न के मिलान का एक उदाहरण यह हो सकता है:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
गलत पहचान से होने वाली समस्याओं से बचने के लिए, Opera ब्राउज़र के लिए पैटर्न-मैच के तौर पर, OPR के अलावा किसी दूसरी स्ट्रिंग का इस्तेमाल करें.
सुरक्षा
इन बदलावों से Android 8.0 (एपीआई लेवल 26) की सुरक्षा पर असर पड़ता है:
- अगर आपके ऐप्लिकेशन का नेटवर्क सुरक्षा कॉन्फ़िगरेशन
cleartext ट्रैफ़िक की सुविधा देने से ऑप्ट
आउट करता है, तो आपके ऐप्लिकेशन के
WebViewऑब्जेक्ट, एचटीटीपी पर वेबसाइटों को ऐक्सेस नहीं कर सकते. इसके बजाय, हरWebViewऑब्जेक्ट को एचटीटीपीएस का इस्तेमाल करना चाहिए. - अनजान सोर्स को अनुमति दें सिस्टम सेटिंग हटा दी गई है. इसकी जगह, अनजान ऐप्लिकेशन इंस्टॉल करें अनुमति से, अज्ञात सोर्स से अनजान ऐप्लिकेशन इंस्टॉल होने को मैनेज किया जाता है. इस नई अनुमति के बारे में ज़्यादा जानने के लिए, अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमतियों वाली गाइड देखें.
अपने ऐप्लिकेशन को ज़्यादा सुरक्षित बनाने के बारे में ज़्यादा दिशा-निर्देश पाने के लिए, Android डेवलपर के लिए सुरक्षा देखें.
खाते का ऐक्सेस और उसे खोजना
Android 8.0 (API लेवल 26) में, ऐप्लिकेशन अब उपयोगकर्ता खातों को तब तक ऐक्सेस नहीं कर सकते, जब तक कि पुष्टि करने वाले टूल के पास खातों का मालिकाना हक न हो या उपयोगकर्ता ने ऐप्लिकेशन को ऐक्सेस न दिया हो. अब GET_ACCOUNTS अनुमति काफ़ी नहीं है. किसी खाते का ऐक्सेस देने के लिए, ऐप्लिकेशन को AccountManager.newChooseAccountIntent() या पुष्टि करने वाले किसी खास तरीके का इस्तेमाल करना होगा. खातों का ऐक्सेस मिलने के बाद, कोई ऐप्लिकेशन उन्हें ऐक्सेस करने के लिए AccountManager.getAccounts() को कॉल कर सकता है.
Android 8.0 अब सेवा में नहीं है
LOGIN_ACCOUNTS_CHANGED_ACTION. ऐप्लिकेशन को रनटाइम के दौरान खातों के बारे में अपडेट पाने के लिए, addOnAccountsUpdatedListener() का इस्तेमाल करना चाहिए.
नए एपीआई और खाता ऐक्सेस करने और उसका पता लगाने के लिए जोड़े गए तरीकों के बारे में जानकारी के लिए, इस दस्तावेज़ के नए एपीआई सेक्शन में खाते का ऐक्सेस और उसे खोजने लायक बनाना देखें.
निजता
इन बदलावों से, Android 8.0 (एपीआई लेवल 26) में निजता पर असर पड़ता है.
-
सिस्टम प्रॉपर्टी
net.dns1,net.dns2,net.dns3, औरnet.dns4अब उपलब्ध नहीं हैं. यह एक ऐसा बदलाव है जिससे प्लैटफ़ॉर्म पर निजता को बेहतर बनाने में मदद मिलती है. -
डीएनएस सर्वर जैसी नेटवर्किंग की जानकारी पाने के लिए,
ACCESS_NETWORK_STATEअनुमति वाले ऐप्लिकेशन,NetworkRequestयाNetworkCallbackऑब्जेक्ट रजिस्टर कर सकते हैं. ये क्लास, Android 5.0 (एपीआई लेवल 21) और इसके बाद के वर्शन में उपलब्ध हैं. -
Build.SERIAL का इस्तेमाल नहीं किया जा सकता.
जिन ऐप्लिकेशन को हार्डवेयर का सीरियल नंबर जानने की ज़रूरत है उन्हें
Build.getSerial()वाले नए तरीके का इस्तेमाल करना चाहिए. इसके लिए,READ_PHONE_STATEअनुमति की ज़रूरत होती है. -
LauncherAppsAPI अब वर्क प्रोफ़ाइल ऐप्लिकेशन को प्राइमरी प्रोफ़ाइल के बारे में जानकारी पाने की अनुमति नहीं देता. जब कोई उपयोगकर्ता किसी वर्क प्रोफ़ाइल में होता है, तोLauncherAppsAPI ऐसा व्यवहार करता है जैसे उसी प्रोफ़ाइल ग्रुप में मौजूद अन्य प्रोफ़ाइलों में कोई ऐप्लिकेशन इंस्टॉल न किया गया हो. पहले की तरह ही, एक-दूसरे से जुड़ी हुई प्रोफ़ाइलों को ऐक्सेस करने की कोशिश में सुरक्षा के अपवाद मौजूद होते हैं.
अनुमतियां
Android 8.0 (एपीआई लेवल 26) से पहले के वर्शन में, अगर किसी ऐप्लिकेशन ने रनटाइम के दौरान अनुमति का अनुरोध किया था और अनुमति दे दी गई थी, तो सिस्टम ने ऐप्लिकेशन को गलती से उसी अनुमति ग्रुप की बाकी अनुमतियां भी दे दी थीं और वे अनुमतियां मेनिफ़ेस्ट में रजिस्टर होती थीं.
Android 8.0 को टारगेट करने वाले ऐप्लिकेशन के लिए, इस व्यवहार को ठीक कर दिया गया है. ऐप्लिकेशन को सिर्फ़ वे अनुमतियां दी जाती हैं जिनके लिए उसने साफ़ तौर पर अनुरोध किया है. हालांकि, जब उपयोगकर्ता किसी ऐप्लिकेशन को अनुमति देता है, तब उस अनुमति ग्रुप में अनुमतियों के लिए बाद में किए जाने वाले सभी अनुरोध अपने-आप स्वीकार हो जाते हैं.
उदाहरण के लिए, मान लें कि कोई ऐप्लिकेशन अपने मेनिफ़ेस्ट में READ_EXTERNAL_STORAGE और
WRITE_EXTERNAL_STORAGE, दोनों को शामिल करता है.
ऐप्लिकेशन, READ_EXTERNAL_STORAGE का अनुरोध करता है और
उपयोगकर्ता उसे अनुमति देता है. अगर ऐप्लिकेशन, एपीआई लेवल 25 या उससे पहले के वर्शन को टारगेट करता है, तो सिस्टम एक ही समय पर WRITE_EXTERNAL_STORAGE भी देता है. ऐसा इसलिए होता है, क्योंकि यह STORAGE अनुमति ग्रुप से जुड़ा है और इसे मेनिफ़ेस्ट में भी रजिस्टर किया गया है. अगर ऐप्लिकेशन Android 8.0 (एपीआई लेवल 26) को टारगेट करता है, तो सिस्टम उस समय सिर्फ़ READ_EXTERNAL_STORAGE देता है. हालांकि, अगर ऐप्लिकेशन बाद में WRITE_EXTERNAL_STORAGE का अनुरोध करता है, तो सिस्टम उपयोगकर्ता से पूछे बिना तुरंत वह ऐक्सेस देता है.
मीडिया
- फ़्रेमवर्क अपने-आप ऑडियो डकिंग कर सकता है. इस मामले में, जब कोई दूसरा ऐप्लिकेशन
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKके साथ फ़ोकस का अनुरोध करता है, तो फ़ोकस में मौजूद ऐप्लिकेशन का वॉल्यूम कम हो जाता है. हालांकि, आम तौर पर उसेonAudioFocusChange()का कॉलबैक नहीं मिलता और ऑडियो फ़ोकस नहीं हटता. जिन ऐप्लिकेशन को डक करने के बजाय रोकना है उनके लिए, इस व्यवहार को बदलने के लिए नए एपीआई उपलब्ध हैं. - जब उपयोगकर्ता कोई फ़ोन कॉल लेता है, तो कॉल के दौरान चालू मीडिया स्ट्रीम म्यूट हो जाती हैं.
- ऑडियो से जुड़े सभी एपीआई को ऑडियो चलाने के इस्तेमाल के उदाहरण के बारे में बताने के लिए, ऑडियो स्ट्रीम टाइप के बजाय
AudioAttributesका इस्तेमाल करना चाहिए. सिर्फ़ वॉल्यूम कंट्रोल के लिए, ऑडियो स्ट्रीम टाइप का इस्तेमाल करना जारी रखें. स्ट्रीम टाइप के अन्य इस्तेमाल अब भी काम करते हैं (उदाहरण के लिए, इस्तेमाल में न होने वालेAudioTrackकन्स्ट्रक्टर के लिएstreamTypeआर्ग्युमेंट), लेकिन सिस्टम इसे गड़बड़ी के तौर पर लॉग करता है. AudioTrackका इस्तेमाल करते समय, अगर ऐप्लिकेशन काफ़ी बड़े ऑडियो बफ़र का अनुरोध करता है, तो फ़्रेमवर्क, डीप बफ़र आउटपुट का इस्तेमाल करने की कोशिश करेगा. हालांकि, ऐसा तब ही होगा, जब डीप बफ़र आउटपुट उपलब्ध हो.- Android 8.0 (एपीआई लेवल 26) में, मीडिया बटन इवेंट को मैनेज करने का तरीका अलग है:
- यूज़र इंटरफ़ेस (यूआई) की गतिविधि में मीडिया बटन के इस्तेमाल में कोई बदलाव नहीं हुआ है: मीडिया बटन इवेंट को मैनेज करने के लिए, फ़ोरग्राउंड गतिविधियों को अब भी प्राथमिकता दी जाती है.
- अगर फ़ोरग्राउंड गतिविधि, मीडिया बटन इवेंट को मैनेज नहीं करती है, तो सिस्टम उस ऐप्लिकेशन पर इवेंट को भेजता है जिसने हाल ही में ऑडियो को स्थानीय तौर पर चलाया था. किस ऐप्लिकेशन में मीडिया के बटन इवेंट मिलेंगे, इसका पता लगाते समय किसी मीडिया सेशन के चालू होने की स्थिति, फ़्लैग, और वीडियो चलाने की स्थिति को ध्यान में नहीं रखा जाता है.
- अगर ऐप्लिकेशन का मीडिया सेशन रिलीज़ हो गया है, तो सिस्टम, ऐप्लिकेशन के
MediaButtonReceiverमें मीडिया बटन इवेंट भेजता है. हालांकि, ऐसा तब ही होता है, जब ऐप्लिकेशन मेंMediaButtonReceiverहो. - अन्य सभी मामलों में, सिस्टम मीडिया बटन इवेंट को खारिज कर देता है.
स्थानीय लाइब्रेरी
Android 8.0 (एपीआई लेवल 26) को टारगेट करने वाले ऐप्लिकेशन में, नेटिव लाइब्रेरी अब तब लोड नहीं होतीं, जब तक उनमें कोई ऐसा लोड सेगमेंट शामिल न हो जिसे लिखा और चलाया जा सकता हो. अगर कुछ ऐप्लिकेशन में गलत लोड सेगमेंट वाली नेटिव लाइब्रेरी हैं, तो इस बदलाव की वजह से वे काम करना बंद कर सकते हैं. यह सुरक्षा को मज़बूत करने का एक तरीका है.
ज़्यादा जानकारी के लिए, लिखे जा सकने वाले और चलाए जा सकने वाले सेगमेंट देखें.
लिंकर में किए गए बदलाव, उस एपीआई लेवल से जुड़े होते हैं जिसे ऐप्लिकेशन टारगेट करता है. अगर टारगेट किए गए एपीआई लेवल पर लिंकर में कोई बदलाव किया जाता है, तो ऐप्लिकेशन लाइब्रेरी को लोड नहीं कर सकता. अगर आपने एपीआई लेवल के उस लेवल से कम एपीआई लेवल को टारगेट किया है जहां लिंकर में बदलाव होता है, तो logcat एक चेतावनी दिखाता है.
कलेक्शन मैनेज करना
Android 8.0 (एपीआई लेवल 26) में,
Collections.sort() को List.sort() के ऊपर
लागू किया जाता है. Android 7.x (एपीआई लेवल 24 और 25) में, यह उलटा था: List.sort() को डिफ़ॉल्ट तौर पर लागू करने को Collections.sort() कहा जाता है.
इस बदलाव से, Collections.sort() को ऑप्टिमाइज़ किए गए List.sort() लागू करने का फ़ायदा मिलता है. हालांकि, इसमें ये पाबंदियां हैं:
List.sort()को लागू करने के लिए,Collections.sort()को कॉल नहीं किया जाना चाहिए, क्योंकि ऐसा करने पर अनलिमिटेड रेक्यूर्सन की वजह से स्टैक ओवरफ़्लो हो जाएगा. इसके बजाय, अगर आपकोListलागू करने के लिए डिफ़ॉल्ट व्यवहार चाहिए, तो आपकोsort()को बदलने से बचना चाहिए.अगर कोई पैरंट क्लास
sort()को गलत तरीके से लागू करती है, तो आम तौर परList.sort()कोList.toArray(),Arrays.sort(), औरListIterator.set()के आधार पर बनाए गए लागू करने के तरीके से बदला जा सकता है. उदाहरण के लिए:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
ज़्यादातर मामलों में,
List.sort()को ऐसे लागू करने की सुविधा भी दी जा सकती है जो एपीआई लेवल के आधार पर, डिफ़ॉल्ट रूप से लागू होने वाले अलग-अलग तरीकों को लागू करती है. उदाहरण के लिए:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
अगर आपने ऐसा सिर्फ़ इसलिए किया है, ताकि सभी एपीआई लेवल पर
sort()तरीका उपलब्ध हो, तोsort()को बदलने के बजाय, उसे कोई यूनीक नाम दें. जैसे,sortCompat().-
Collections.sort()अबsort()को कॉल करने वाली सूची के लागू होने में, स्ट्रक्चर में बदलाव के तौर पर गिना जाता है. उदाहरण के लिए, Android 8.0 (एपीआई लेवल 26) से पहले के प्लैटफ़ॉर्म के वर्शन में, किसीArrayListपर बार-बार फिरना और फिराने के दौरान उस परsort()को कॉल करने पर,ConcurrentModificationExceptionदिखता था. ऐसा तब होता था, जबList.sort()को कॉल करके क्रम से लगाने की प्रोसेस की जाती थी.Collections.sort()ने कोई अपवाद नहीं दिया.इस बदलाव से, प्लैटफ़ॉर्म का व्यवहार ज़्यादा बेहतर हो जाता है: अब दोनों तरीकों से
ConcurrentModificationExceptionमिलता है.
क्लास लोड करने का तरीका
Android 8.0 (एपीआई लेवल 26) यह पक्का करता है कि नई क्लास लोड करते समय, क्लास लोडर रनटाइम की मान्यताओं को न तोड़ें. ये जांच, चाहे क्लास का रेफ़रंस Java (forName() से),
Dalvik बाइटकोड या JNI से लिया गया हो, की जाती हैं. यह प्लैटफ़ॉर्म, Java से loadClass() तरीके पर किए गए डायरेक्ट कॉल को इंटरसेप्ट नहीं करता. साथ ही, ऐसे कॉल के नतीजों की जांच भी नहीं करता. इस व्यवहार से, सही तरीके से काम करने वाले क्लास लोडर के काम करने पर कोई असर नहीं पड़ना चाहिए.
प्लैटफ़ॉर्म यह जांच करता है कि क्लास लोडर से मिलने वाले क्लास का डिस्क्रिप्टर, अनुमानित डिस्क्रिप्टर से मेल खाता है या नहीं. अगर दिखाया गया डिस्क्रिप्टर मेल नहीं खाता है, तो प्लैटफ़ॉर्म NoClassDefFoundError गड़बड़ी का मैसेज दिखाता है. साथ ही, अपवाद में अंतर की जानकारी देने वाला मैसेज सेव करता है.
प्लैटफ़ॉर्म यह भी जांच करता है कि अनुरोध की गई क्लास के डिस्क्रिप्टर मान्य हैं या नहीं. यह जांच, GetFieldID() जैसी क्लास को अप्रत्यक्ष रूप से लोड करने वाले JNI कॉल को पकड़ती है. साथ ही, उन क्लास को अमान्य डिस्क्रिप्टर पास करती है. उदाहरण के लिए, हस्ताक्षर java/lang/String वाला फ़ील्ड नहीं मिला, क्योंकि हस्ताक्षर अमान्य है. यह Ljava/lang/String; होना चाहिए.
यह FindClass() के लिए JNI कॉल से अलग है
जहां java/lang/String एक मान्य और पूरी तरह से क्वालिफ़ाइड नाम है.
Android 8.0 (एपीआई लेवल 26) पर यह सुविधा काम नहीं करती कि एक से ज़्यादा क्लास लोडर, एक ही DexFile ऑब्जेक्ट का इस्तेमाल करके क्लास तय करने की कोशिश करें. ऐसा करने पर, Android रनटाइम में InternalError
गड़बड़ी का मैसेज दिखता है. इसमें, "एक से ज़्यादा क्लास लोडर के साथ dex फ़ाइल <filename> को रजिस्टर करने की कोशिश की गई" लिखा होता है.
DexFile API अब काम नहीं करता. हमारा सुझाव है कि आप इसके बजाय, PathClassLoader या
BaseDexClassLoader जैसे किसी प्लैटफ़ॉर्म क्लासलोडर का इस्तेमाल करें.
ध्यान दें: एक से ज़्यादा क्लास लोडर बनाए जा सकते हैं, जो फ़ाइल सिस्टम से एक ही APK या JAR फ़ाइल कंटेनर का रेफ़रंस देते हैं. ऐसा करने से, आम तौर पर
ज़्यादा मेमोरी नहीं बनती: अगर कंटेनर में DEX फ़ाइलों को कंप्रेस करने के बजाय सेव किया जाता है, तो प्लैटफ़ॉर्म सीधे तौर पर एक्सट्रैक्ट करने के बजाय, उन पर mmap कार्रवाई कर सकता है. हालांकि, अगर प्लैटफ़ॉर्म को कंटेनर से DEX फ़ाइल निकालनी है, तो इस तरह से DEX फ़ाइल का रेफ़रंस देने पर, ज़्यादा मेमोरी खर्च हो सकती है.
Android में, सभी क्लास लोडर को एक साथ काम करने वाला माना जाता है. जब कई थ्रेड एक ही क्लास लोडर से एक ही क्लास को लोड करने की कोशिश करते हैं, तो कार्रवाई को पूरा करने वाला पहला थ्रेड जीत जाता है और नतीजा दूसरे थ्रेड के लिए इस्तेमाल किया जाता है. यह व्यवहार तब भी होता है, जब क्लास लोडर ने एक ही क्लास, कोई दूसरी क्लास या कोई अपवाद दिखाया हो. प्लैटफ़ॉर्म ऐसे अपवादों को अनदेखा कर देता है.
चेतावनी: Android 8.0 (एपीआई लेवल 26) से पहले के प्लैटफ़ॉर्म में, इन अनुमानों को तोड़ने से एक ही क्लास को कई बार परिभाषित किया जा सकता है. साथ ही, क्लास के भ्रम की वजह से गड़बड़ी हो सकती है और दूसरे अनचाहे नतीजे मिल सकते हैं.