ऐक्टिविटी को एम्बेड करने की सुविधा, बड़ी स्क्रीन वाले डिवाइसों पर ऐप्लिकेशन को ऑप्टिमाइज़ करती है. इसके लिए, ऐप्लिकेशन की टास्क विंडो को दो ऐक्टिविटी या एक ही ऐक्टिविटी के दो इंस्टेंस के बीच बांटा जाता है.
अगर आपके ऐप्लिकेशन में कई गतिविधियां शामिल हैं, तो गतिविधि को एम्बेड करने की सुविधा की मदद से, टेबलेट, फ़ोल्ड किए जा सकने वाले डिवाइसों, और ChromeOS डिवाइसों पर बेहतर उपयोगकर्ता अनुभव दिया जा सकता है.
गतिविधि को एम्बेड करने के लिए, कोड में बदलाव करने की ज़रूरत नहीं होती. एक्सएमएल कॉन्फ़िगरेशन फ़ाइल बनाकर या Jetpack WindowManager एपीआई कॉल करके, यह तय किया जा सकता है कि आपका ऐप्लिकेशन अपनी गतिविधियों को कैसे दिखाएगा—एक साथ या स्टैक किया गया.
छोटी स्क्रीन के लिए, यह सुविधा अपने-आप काम करती रहती है. जब आपका ऐप्लिकेशन, छोटी स्क्रीन वाले डिवाइस पर होता है, तो ऐक्टिविटी एक-दूसरे के ऊपर स्टैक होती हैं. बड़ी स्क्रीन पर, गतिविधियां एक साथ दिखती हैं. सिस्टम, आपके बनाए गए कॉन्फ़िगरेशन के आधार पर प्रज़ेंटेशन तय करता है. इसके लिए, आपको ब्रैंचिंग लॉजिक की ज़रूरत नहीं है.
गतिविधि को एम्बेड करने की सुविधा, डिवाइस के ओरिएंटेशन में होने वाले बदलावों के साथ काम करती है. साथ ही, यह फ़ोल्ड किए जा सकने वाले डिवाइसों पर आसानी से काम करती है. डिवाइस के फ़ोल्ड और अनफ़ोल्ड होने पर, गतिविधियों को स्टैक और अनस्टैक किया जा सकता है.
गतिविधि को एम्बेड करने की सुविधा, Android 12L (एपीआई लेवल 32) और उसके बाद के वर्शन वाले ज़्यादातर बड़े स्क्रीन वाले डिवाइसों पर काम करती है.
टास्क विंडो को स्प्लिट करना
गतिविधि को एम्बेड करने से, ऐप्लिकेशन की टास्क विंडो दो कंटेनर में बंट जाती है: प्राइमरी और सेकंडरी. कंटेनर में, मुख्य गतिविधि से लॉन्च की गई गतिविधियां या पहले से मौजूद अन्य गतिविधियां होती हैं.
ऐक्टिविटी लॉन्च होने के साथ ही, सेकंडरी कंटेनर में स्टैक हो जाती हैं. साथ ही, छोटी स्क्रीन पर सेकंडरी कंटेनर, प्राइमरी कंटेनर के ऊपर स्टैक होता है. इसलिए, ऐक्टिविटी स्टैक करने और बैक नेविगेशन की सुविधा, आपके ऐप्लिकेशन में पहले से मौजूद ऐक्टिविटी के क्रम के हिसाब से काम करती है.
गतिविधि को एम्बेड करने की सुविधा की मदद से, गतिविधियों को कई तरह से दिखाया जा सकता है. आपका ऐप्लिकेशन, एक साथ दो गतिविधियों को लॉन्च करके, टास्क विंडो को बांट सकता है:
इसके अलावा, अगर कोई गतिविधि पूरी टास्क विंडो में दिख रही है, तो उसके बगल में नई गतिविधि लॉन्च करके, विंडो को स्प्लिट किया जा सकता है:
जो गतिविधियां पहले से ही स्प्लिट स्क्रीन में हैं और टास्क विंडो शेयर कर रही हैं वे इन तरीकों से दूसरी गतिविधियां लॉन्च कर सकती हैं:
किसी दूसरी गतिविधि के ऊपर बाईं ओर:
स्प्लिट स्क्रीन को बगल में ले जाएं और उसे बगल में शिफ़्ट करें. इससे पिछली मुख्य गतिविधि छिप जाएगी:
किसी ऐक्टिविटी को सबसे ऊपर लॉन्च करें. इसका मतलब है कि उसी ऐक्टिविटी स्टैक में:
उसी टास्क में किसी गतिविधि की फ़ुल विंडो लॉन्च करने के लिए:
पिछले पेज पर जाने का नेविगेशन
अलग-अलग तरह के ऐप्लिकेशन में, स्प्लिट टास्क विंडो की स्थिति में, बैक नेविगेशन के अलग-अलग नियम हो सकते हैं. यह इस बात पर निर्भर करता है कि ऐक्टिविटी के बीच किस तरह की डिपेंडेंसी है या उपयोगकर्ता बैक इवेंट को कैसे ट्रिगर करते हैं. उदाहरण के लिए:
- एक साथ होने वाली गतिविधियां: अगर गतिविधियां एक-दूसरे से जुड़ी हैं और एक के बिना दूसरी नहीं दिखाई जानी चाहिए, तो दोनों गतिविधियों को पूरा करने के लिए, बैक नेविगेशन को कॉन्फ़िगर किया जा सकता है.
- अलग-अलग गतिविधियां: अगर गतिविधियां पूरी तरह से अलग-अलग हैं, तो किसी गतिविधि पर बैक नेविगेशन करने से, टास्क विंडो में मौजूद किसी दूसरी गतिविधि की स्थिति पर असर नहीं पड़ता.
बटन नेविगेशन का इस्तेमाल करते समय, बैक इवेंट को फ़ोकस की गई पिछली ऐक्टिविटी पर भेजा जाता है.
जेस्चर वाले नेविगेशन के लिए:
Android 14 (एपीआई लेवल 34) और उससे पहले के वर्शन — बैक इवेंट को उस गतिविधि पर भेजा जाता है जहां जेस्चर हुआ था. जब उपयोगकर्ता स्क्रीन की बाईं ओर से स्वाइप करते हैं, तो स्प्लिट विंडो के बाईं ओर मौजूद पैनल में मौजूद गतिविधि को 'वापस जाएं' इवेंट भेजा जाता है. जब उपयोगकर्ता स्क्रीन की दाईं ओर से स्वाइप करते हैं, तो दाईं ओर मौजूद पैनल में मौजूद गतिविधि को बैक इवेंट भेजा जाता है.
Android 15 (एपीआई लेवल 35) और उसके बाद के वर्शन
एक ही ऐप्लिकेशन की कई गतिविधियों को मैनेज करते समय, स्वाइप करने की दिशा के बावजूद, जेस्चर से सबसे ऊपर मौजूद गतिविधि पूरी हो जाती है. इससे, एक जैसा अनुभव मिलता है.
अलग-अलग ऐप्लिकेशन (ओवरले) की दो गतिविधियों वाले मामलों में, बैक इवेंट को फ़ोकस में मौजूद आखिरी गतिविधि पर भेजा जाता है. यह बटन नेविगेशन के व्यवहार के हिसाब से होता है.
कई पैनल वाला लेआउट
Jetpack WindowManager की मदद से, बड़ी स्क्रीन वाले डिवाइसों पर Android 12L (एपीआई लेवल 32) या उसके बाद के वर्शन और प्लैटफ़ॉर्म के पुराने वर्शन वाले कुछ डिवाइसों पर, एक से ज़्यादा पैनल वाला लेआउट एम्बेड करने वाली गतिविधि बनाई जा सकती है. SlidingPaneLayout
जैसे फ़्रेगमेंट या व्यू-आधारित लेआउट के बजाय, कई गतिविधियों पर आधारित मौजूदा ऐप्लिकेशन, सोर्स कोड को फिर से बनाने के बिना, बड़ी स्क्रीन पर बेहतर उपयोगकर्ता अनुभव दे सकते हैं.
इसका एक सामान्य उदाहरण, सूची और ज़्यादा जानकारी को अलग-अलग करना है. अच्छी क्वालिटी के प्रज़ेंटेशन को पक्का करने के लिए, सिस्टम सूची गतिविधि शुरू करता है. इसके बाद, ऐप्लिकेशन तुरंत ज़्यादा जानकारी वाली गतिविधि शुरू करता है. ट्रांज़िशन सिस्टम तब तक इंतज़ार करता है, जब तक दोनों गतिविधियां ड्रॉ नहीं हो जातीं. इसके बाद, उन्हें एक साथ दिखाता है. उपयोगकर्ता के लिए, ये दोनों ऐक्टिविटी एक साथ लॉन्च होती हैं.
एट्रिब्यूट का बंटवारा
आपके पास यह तय करने का विकल्प होता है कि टास्क विंडो को अलग-अलग कंटेनर के बीच किस तरह बांटा जाए और कंटेनर को एक-दूसरे के हिसाब से कैसे व्यवस्थित किया जाए.
एक्सएमएल कॉन्फ़िगरेशन फ़ाइल में तय किए गए नियमों के लिए, ये एट्रिब्यूट सेट करें:
splitRatio
: कंटेनर के अनुपात सेट करता है. वैल्यू, ओपन इंटरवल (0.0, 1.0) में फ़्लोटिंग पॉइंट नंबर होती है.splitLayoutDirection
: इससे पता चलता है कि अलग-अलग कंटेनर एक-दूसरे के मुकाबले कैसे व्यवस्थित किए गए हैं. वैल्यू में ये शामिल हैं:ltr
: बाएं से दाएंrtl
: दाएं से बाएंlocale
: भाषा की सेटिंग सेltr
याrtl
तय होता है
उदाहरणों के लिए, एक्सएमएल कॉन्फ़िगरेशन सेक्शन देखें.
WindowManager API का इस्तेमाल करके बनाए गए नियमों के लिए, SplitAttributes.Builder
के साथ SplitAttributes
ऑब्जेक्ट बनाएं और इन बिल्डर तरीकों को कॉल करें:
setSplitType()
: स्प्लिट किए गए कंटेनर के अनुपात सेट करता है. मान्य आर्ग्युमेंट के लिए,SplitAttributes.SplitType
देखें. इसमेंSplitAttributes.SplitType.ratio()
तरीका भी शामिल है.setLayoutDirection()
: कंटेनर का लेआउट सेट करता है. संभावित वैल्यू के लिए,SplitAttributes.LayoutDirection
देखें.
उदाहरणों के लिए, WindowManager API सेक्शन देखें.
प्लेसहोल्डर
प्लेसहोल्डर गतिविधियां, खाली सेकंडरी गतिविधियां होती हैं. ये गतिविधि के बंटवारे के एक हिस्से पर होती हैं. इन्हें किसी ऐसी गतिविधि से बदल दिया जाएगा जिसमें कॉन्टेंट शामिल हो. उदाहरण के लिए, प्लेसहोल्डर ऐक्टिविटी, सूची-जानकारी वाले लेआउट में, ऐक्टिविटी के स्प्लिट किए गए हिस्से के दूसरे हिस्से में तब तक रह सकती है, जब तक सूची से कोई आइटम नहीं चुना जाता. इसके बाद, चुने गए सूची आइटम की ज़्यादा जानकारी वाली ऐक्टिविटी, प्लेसहोल्डर की जगह ले लेती है.
डिफ़ॉल्ट रूप से, सिस्टम प्लेसहोल्डर सिर्फ़ तब दिखाता है, जब गतिविधि के बंटवारे के लिए ज़रूरत के मुताबिक जगह हो. जब डिसप्ले का साइज़, स्प्लिट दिखाने के लिए बहुत छोटा हो जाता है, तो प्लेसहोल्डर अपने-आप बंद हो जाते हैं. जब जगह होती है, तो सिस्टम, प्लेसहोल्डर को फिर से शुरू करने की स्थिति के साथ फिर से लॉन्च करता है.
हालांकि, SplitPlaceholder.Builder
के SplitPlaceholderRule
या setSticky()
तरीके के stickyPlaceholder
एट्रिब्यूट की वैल्यू, डिफ़ॉल्ट व्यवहार को बदल सकती है. जब एट्रिब्यूट या तरीके में true
की वैल्यू दी जाती है, तो डिसप्ले को दो पैनल वाले डिसप्ले से एक पैनल वाले डिसप्ले में बदलने पर, सिस्टम टास्क विंडो में प्लेसहोल्डर को सबसे ऊपर की गतिविधि के तौर पर दिखाता है. उदाहरण के लिए, स्प्लिट कॉन्फ़िगरेशन देखें.
विंडो का साइज़ बदलना
जब डिवाइस कॉन्फ़िगरेशन में बदलाव होने पर, टास्क विंडो की चौड़ाई कम हो जाती है, ताकि वह कई पैनल वाले लेआउट के लिए ज़रूरत के मुताबिक बड़ी न हो (उदाहरण के लिए, जब बड़ी स्क्रीन वाला फ़ोल्ड करने वाला डिवाइस, टैबलेट साइज़ से फ़ोन साइज़ में फ़ोल्ड हो जाता है या ऐप्लिकेशन विंडो का साइज़, कई विंडो वाले मोड में बदल जाता है), तो टास्क विंडो के सेकंडरी पैनल में मौजूद ऐसी ऐक्टिविटी जो प्लेसहोल्डर नहीं हैं उन्हें प्राइमरी पैनल में मौजूद ऐक्टिविटी के ऊपर स्टैक किया जाता है.
प्लेसहोल्डर गतिविधियां सिर्फ़ तब दिखाई जाती हैं, जब स्प्लिट के लिए डिसप्ले की चौड़ाई काफ़ी हो. छोटी स्क्रीन पर, प्लेसहोल्डर अपने-आप हट जाता है. जब डिसप्ले एरिया फिर से ज़रूरत के मुताबिक बड़ा हो जाता है, तो प्लेसहोल्डर फिर से बन जाता है. (प्लेसहोल्डर सेक्शन देखें.)
गतिविधि को स्टैक किया जा सकता है, क्योंकि WindowManager, सेकंडरी पैनल में मौजूद गतिविधियों को प्राइमरी पैनल में मौजूद गतिविधियों के ऊपर z-क्रम में लगाता है.
सेकंडरी पैनल में कई गतिविधियां
गतिविधि B, गतिविधि C को बिना किसी अतिरिक्त इंटेंट फ़्लैग के शुरू करती है:
इस वजह से, एक ही टास्क में गतिविधियों का z-क्रम इस तरह दिखता है:
इसलिए, छोटी टास्क विंडो में, ऐप्लिकेशन एक गतिविधि में सिकुड़ जाता है, जिसमें स्टैक के सबसे ऊपर C होता है:
छोटी विंडो में वापस जाने पर, एक-दूसरे के ऊपर स्टैक की गई गतिविधियों पर नेविगेट किया जा सकता है.
अगर टास्क विंडो के कॉन्फ़िगरेशन को बड़े साइज़ में वापस लाया जाता है, ताकि उसमें कई पैनल आ सकें, तो गतिविधियां फिर से एक साथ दिखती हैं.
स्टैक किए गए स्प्लिट
ऐक्टिविटी B, ऐक्टिविटी C को साइड में शुरू करती है और स्प्लिट स्क्रीन को साइड में ले जाती है:
इसकी वजह से, एक ही टास्क में गतिविधियों का ज़ेड-ऑर्डर इस तरह दिखता है:
छोटी टास्क विंडो में, ऐप्लिकेशन एक गतिविधि में सिकुड़ जाता है, जिसमें सबसे ऊपर C होता है:
फ़िक्स्ड-पोर्ट्रेट ओरिएंटेशन
android:screenOrientation मेनिफ़ेस्ट सेटिंग की मदद से, ऐप्लिकेशन में ऐक्टिविटी को पोर्ट्रेट या लैंडस्केप ओरिएंटेशन में सीमित किया जा सकता है. टैबलेट और फ़ोल्ड किए जा सकने वाले डिवाइसों जैसी बड़ी स्क्रीन वाले डिवाइसों पर उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, डिवाइस मैन्युफ़ैक्चरर (OEM) स्क्रीन ओरिएंटेशन के अनुरोधों को अनदेखा कर सकते हैं. साथ ही, लैंडस्केप डिसप्ले पर ऐप्लिकेशन को पोर्ट्रेट ओरिएंटेशन में लेटरबॉक्स कर सकते हैं या पोर्ट्रेट डिसप्ले पर ऐप्लिकेशन को लैंडस्केप ओरिएंटेशन में लेटरबॉक्स कर सकते हैं.
इसी तरह, गतिविधि को एम्बेड करने की सुविधा चालू होने पर, OEM बड़ी स्क्रीन (चौड़ाई ≥ 600dp) पर, लैंडस्केप ओरिएंटेशन में लेटरबॉक्स फ़िक्स्ड-पोर्ट्रेट गतिविधियों के लिए, डिवाइसों को पसंद के मुताबिक बना सकते हैं. जब कोई फ़िक्स्ड-पोर्ट्रेट ऐक्टिविटी दूसरी ऐक्टिविटी को लॉन्च करती है, तो डिवाइस दो पैनल वाले डिसप्ले में, दोनों ऐक्टिविटी को एक साथ दिखा सकता है.
डिवाइसों को यह बताने के लिए कि आपका ऐप्लिकेशन गतिविधि को एम्बेड करने की सुविधा के साथ काम करता है, अपनी ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल में हमेशा android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
प्रॉपर्टी जोड़ें. स्प्लिट कॉन्फ़िगरेशन सेक्शन देखें. इसके बाद, OEM के हिसाब से बनाए गए डिवाइस यह तय कर सकते हैं कि फ़िक्स्ड-पोर्ट्रेट गतिविधियों को लेटरबॉक्स में दिखाना है या नहीं.
स्प्लिट कॉन्फ़िगरेशन
स्प्लिट रूल, गतिविधि के बंटवारे को कॉन्फ़िगर करते हैं. स्प्लिट नियमों को एक्सएमएल कॉन्फ़िगरेशन फ़ाइल में या Jetpack WindowManager एपीआई कॉल करके तय किया जाता है.
दोनों ही मामलों में, आपके ऐप्लिकेशन को WindowManager लाइब्रेरी को ऐक्सेस करना होगा. साथ ही, उसे सिस्टम को यह बताना होगा कि ऐप्लिकेशन ने गतिविधि को एम्बेड करने की सुविधा लागू की है.
ये काम करें:
अपने ऐप्लिकेशन के मॉड्यूल-लेवल वाली
build.gradle
फ़ाइल में, WindowManager लाइब्रेरी की सबसे नई डिपेंडेंसी जोड़ें. उदाहरण के लिए:implementation 'androidx.window:window:1.1.0-beta02'
WindowManager लाइब्रेरी, गतिविधि को एम्बेड करने के लिए ज़रूरी सभी कॉम्पोनेंट उपलब्ध कराती है.
सिस्टम को बताएं कि आपके ऐप्लिकेशन में गतिविधि को एम्बेड करने की सुविधा लागू की गई है.
ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल के <application> एलिमेंट में
android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
प्रॉपर्टी जोड़ें और वैल्यू को 'सही' पर सेट करें. उदाहरण के लिए:<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <property android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED" android:value="true" /> </application> </manifest>
WindowManager के रिलीज़ 1.1.0-alpha06 और उसके बाद के वर्शन में, ऐक्टिविटी को एम्बेड करने के लिए स्प्लिट की सुविधा तब तक बंद रहती है, जब तक प्रॉपर्टी को मेनिफ़ेस्ट में जोड़कर 'सही' पर सेट नहीं किया जाता.
साथ ही, डिवाइस बनाने वाली कंपनियां इस सेटिंग का इस्तेमाल, गतिविधि को जोड़ने की सुविधा वाले ऐप्लिकेशन के लिए कस्टम सुविधाएं चालू करने के लिए करती हैं. उदाहरण के लिए, डिवाइसों पर सिर्फ़ पोर्ट्रेट मोड में चलने वाली गतिविधि को, लैंडस्केप डिसप्ले पर लेटरबॉक्स किया जा सकता है. ऐसा इसलिए किया जाता है, ताकि दूसरी गतिविधि शुरू होने पर, गतिविधि को दो पैनल वाले लेआउट में ट्रांज़िशन किया जा सके. ज़्यादा जानकारी के लिए, पोर्ट्रेट मोड में फ़िक्स किया गया ओरिएंटेशन देखें.
एक्सएमएल कॉन्फ़िगरेशन
गतिविधि को एम्बेड करने के लिए, एक्सएमएल पर आधारित लागू करने का तरीका बनाने के लिए, यह तरीका अपनाएं:
ऐसी एक्सएमएल रिसॉर्स फ़ाइल बनाएं जो ये काम करती हो:
- उन गतिविधियों के बारे में बताता है जो एक ही स्प्लिट शेयर करती हैं
- स्प्लिट के विकल्पों को कॉन्फ़िगर करता है
- कॉन्टेंट उपलब्ध न होने पर, स्प्लिट के सेकंडरी कंटेनर के लिए प्लेसहोल्डर बनाता है
- उन गतिविधियों के बारे में बताता है जिन्हें कभी भी स्प्लिट का हिस्सा नहीं बनाया जाना चाहिए
उदाहरण के लिए:
<!-- main_split_config.xml --> <resources xmlns:window="http://schemas.android.com/apk/res-auto"> <!-- Define a split for the named activities. --> <SplitPairRule window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:finishPrimaryWithSecondary="never" window:finishSecondaryWithPrimary="always" window:clearTop="false"> <SplitPairFilter window:primaryActivityName=".ListActivity" window:secondaryActivityName=".DetailActivity"/> </SplitPairRule> <!-- Specify a placeholder for the secondary container when content is not available. --> <SplitPlaceholderRule window:placeholderActivityName=".PlaceholderActivity" window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:stickyPlaceholder="false"> <ActivityFilter window:activityName=".ListActivity"/> </SplitPlaceholderRule> <!-- Define activities that should never be part of a split. Note: Takes precedence over other split rules for the activity named in the rule. --> <ActivityRule window:alwaysExpand="true"> <ActivityFilter window:activityName=".ExpandedActivity"/> </ActivityRule> </resources>
कोई इनिशलाइज़र बनाएं.
WindowManager
RuleController
कॉम्पोनेंट, एक्सएमएल कॉन्फ़िगरेशन फ़ाइल को पार्स करता है और सिस्टम के लिए नियम उपलब्ध कराता है. Jetpack की स्टार्टअप लाइब्रेरीInitializer
, ऐप्लिकेशन के स्टार्टअप के समयRuleController
के लिए एक्सएमएल फ़ाइल उपलब्ध कराती है, ताकि कोई भी गतिविधि शुरू होने पर नियम लागू हो सकें.कोई इनिशलाइज़र बनाने के लिए, यह तरीका अपनाएं:
अपने मॉड्यूल-लेवल की
build.gradle
फ़ाइल में, Jetpack Startup लाइब्रेरी की सबसे नई डिपेंडेंसी जोड़ें. उदाहरण के लिए:implementation 'androidx.startup:startup-runtime:1.1.1'
ऐसी क्लास बनाएं जो
Initializer
इंटरफ़ेस को लागू करती हो.इनिशियलाइज़र,
RuleController.parseRules()
तरीके को एक्सएमएल कॉन्फ़िगरेशन फ़ाइल (main_split_config.xml
) का आईडी पास करके,RuleController
के लिए स्प्लिट नियम उपलब्ध कराता है.Kotlin
class SplitInitializer : Initializer<RuleController> { override fun create(context: Context): RuleController { return RuleController.getInstance(context).apply { setRules(RuleController.parseRules(context, R.xml.main_split_config)) } } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
Java
public class SplitInitializer implements Initializer<RuleController> { @NonNull @Override public RuleController create(@NonNull Context context) { RuleController ruleController = RuleController.getInstance(context); ruleController.setRules( RuleController.parseRules(context, R.xml.main_split_config) ); return ruleController; } @NonNull @Override public List<Class<? extends Initializer<?>>> dependencies() { return Collections.emptyList(); } }
नियमों की परिभाषाओं के लिए कॉन्टेंट प्रोवाइडर बनाएं.
अपनी ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल में,
<provider>
के तौर परandroidx.startup.InitializationProvider
जोड़ें. अपनेRuleController
initializer,SplitInitializer
को लागू करने का रेफ़रंस शामिल करें:<!-- AndroidManifest.xml --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <!-- Make SplitInitializer discoverable by InitializationProvider. --> <meta-data android:name="${applicationId}.SplitInitializer" android:value="androidx.startup" /> </provider>
ऐप्लिकेशन के
onCreate()
तरीके को कॉल करने से पहले,InitializationProvider
SplitInitializer
को ढूंढता और शुरू करता है. इस वजह से, ऐप्लिकेशन की मुख्य गतिविधि शुरू होने पर, स्प्लिट के नियम लागू होते हैं.
WindowManager API
कुछ एपीआई कॉल की मदद से, प्रोग्राम के हिसाब से गतिविधि को एम्बेड किया जा सकता है. Application
के किसी सबक्लास के onCreate()
तरीके में कॉल करें, ताकि यह पक्का किया जा सके कि किसी भी गतिविधि के शुरू होने से पहले नियम लागू हों.
प्रोग्राम के हिसाब से गतिविधि का बंटवारा करने के लिए, यह तरीका अपनाएं:
स्प्लिट नियम बनाएं:
एक
SplitPairFilter
बनाएं, जो उन गतिविधियों की पहचान करता हो जो स्प्लिट शेयर करते हैं:Kotlin
val splitPairFilter = SplitPairFilter( ComponentName(this, ListActivity::class.java), ComponentName(this, DetailActivity::class.java), null )
Java
SplitPairFilter splitPairFilter = new SplitPairFilter( new ComponentName(this, ListActivity.class), new ComponentName(this, DetailActivity.class), null );
फ़िल्टर को फ़िल्टर सेट में जोड़ें:
Kotlin
val filterSet = setOf(splitPairFilter)
Java
Set<SplitPairFilter> filterSet = new HashSet<>(); filterSet.add(splitPairFilter);
स्प्लिट के लिए लेआउट एट्रिब्यूट बनाएं:
Kotlin
val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build()
Java
final SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build();
SplitAttributes.Builder
, लेआउट एट्रिब्यूट वाला ऑब्जेक्ट बनाता है:setSplitType()
: इससे यह तय होता है कि उपलब्ध डिसप्ले एरिया को हर गतिविधि कंटेनर में कैसे बांटा जाता है. अनुपात के बंटवारे के टाइप से, मुख्य कंटेनर के लिए उपलब्ध डिसप्ले एरिया का अनुपात पता चलता है. बाकी बचे डिसप्ले एरिया पर सेकंडरी कंटेनर का कब्जा होता है.setLayoutDirection()
: इससे पता चलता है कि गतिविधि कंटेनर एक-दूसरे के मुकाबले कैसे व्यवस्थित किए गए हैं. सबसे पहले प्राइमरी कंटेनर को व्यवस्थित किया जाता है.
SplitPairRule
बनाएं:Kotlin
val splitPairRule = SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build()
Java
SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build();
SplitPairRule.Builder
नियम बनाता और कॉन्फ़िगर करता है:filterSet
: इसमें स्प्लिट पेयर फ़िल्टर होते हैं, जो स्प्लिट शेयर करने वाली गतिविधियों की पहचान करके, यह तय करते हैं कि नियम कब लागू किया जाए.setDefaultSplitAttributes()
: नियम पर लेआउट एट्रिब्यूट लागू करता है.setMinWidthDp()
: डिसप्ले की कम से कम चौड़ाई (डेंसिटी-इंडिपेंडेंट पिक्सल, डीपी में) सेट करता है, ताकि स्प्लिट किया जा सके.setMinSmallestWidthDp()
: डिवाइस के ओरिएंटेशन के बावजूद, स्प्लिट मोड चालू करने के लिए, दो डिसप्ले डाइमेंशन में से छोटे डाइमेंशन की कम से कम वैल्यू (dp में) सेट करता है.setMaxAspectRatioInPortrait()
: पोर्ट्रेट ओरिएंटेशन में, डिसप्ले का ज़्यादा से ज़्यादा आसपेक्ट रेशियो (ऊंचाई:चौड़ाई) सेट करता है. इस आसपेक्ट रेशियो में गतिविधि के स्प्लिट दिखाए जाते हैं. अगर किसी पोर्ट्रेट डिसप्ले का आसपेक्ट रेशियो, ज़्यादा से ज़्यादा आसपेक्ट रेशियो से ज़्यादा है, तो डिसप्ले की चौड़ाई के बावजूद स्प्लिट की सुविधा बंद हो जाती है. ध्यान दें: डिफ़ॉल्ट वैल्यू 1.4 होती है. इसकी वजह से, ज़्यादातर टैबलेट पर गतिविधियां, पोर्ट्रेट ओरिएंटेशन में पूरी टास्क विंडो में दिखती हैं.SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
औरsetMaxAspectRatioInLandscape()
लेख भी पढ़ें. लैंडस्केप के लिए डिफ़ॉल्ट वैल्यूALWAYS_ALLOW
है.setFinishPrimaryWithSecondary()
: इससे यह तय होता है कि सेकंडरी कंटेनर में सभी गतिविधियां पूरी होने पर, प्राइमरी कंटेनर में गतिविधियों पर क्या असर पड़ता है.NEVER
से पता चलता है कि सेकंडरी कंटेनर में सभी गतिविधियां पूरी होने के बाद, सिस्टम को मुख्य गतिविधियां पूरी नहीं करनी चाहिए. ज़्यादा जानकारी के लिए, गतिविधियां पूरी करना लेख पढ़ें.setFinishSecondaryWithPrimary()
: इससे यह सेट होता है कि मुख्य कंटेनर में सभी गतिविधियां पूरी करने से, सेकंडरी कंटेनर में मौजूद गतिविधियों पर क्या असर पड़ता है.ALWAYS
से पता चलता है कि प्राइमरी कंटेनर में सभी गतिविधियां पूरी होने के बाद, सिस्टम को हमेशा सेकंडरी कंटेनर में मौजूद गतिविधियां पूरी करनी चाहिए. ज़्यादा जानकारी के लिए, गतिविधियां पूरी करना लेख पढ़ें.setClearTop()
: इससे पता चलता है कि कंटेनर में नई गतिविधि शुरू होने पर, सेकंडरी कंटेनर में मौजूद सभी गतिविधियां पूरी हो गई हैं या नहीं.false
वैल्यू से पता चलता है कि नई गतिविधियां, सेकंडरी कंटेनर में पहले से मौजूद गतिविधियों के ऊपर स्टैक की जाती हैं.
WindowManager
RuleController
का सिंगलटन इंस्टेंस पाएं और नियम जोड़ें:Kotlin
val ruleController = RuleController.getInstance(this) ruleController.addRule(splitPairRule)
Java
RuleController ruleController = RuleController.getInstance(this); ruleController.addRule(splitPairRule);
कॉन्टेंट उपलब्ध न होने पर, सेकंडरी कंटेनर के लिए प्लेसहोल्डर बनाएं:
ActivityFilter
बनाएं, जो उस गतिविधि की पहचान करता है जिसके साथ प्लेसहोल्डर, टास्क विंडो का स्प्लिट शेयर करता है:Kotlin
val placeholderActivityFilter = ActivityFilter( ComponentName(this, ListActivity::class.java), null )
Java
ActivityFilter placeholderActivityFilter = new ActivityFilter( new ComponentName(this, ListActivity.class), null );
फ़िल्टर को फ़िल्टर सेट में जोड़ें:
Kotlin
val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
Java
Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>(); placeholderActivityFilterSet.add(placeholderActivityFilter);
SplitPlaceholderRule
बनाएं:Kotlin
val splitPlaceholderRule = SplitPlaceholderRule.Builder( placeholderActivityFilterSet, Intent(context, PlaceholderActivity::class.java) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build()
Java
SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder( placeholderActivityFilterSet, new Intent(context, PlaceholderActivity.class) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build();
SplitPlaceholderRule.Builder
नियम बनाता और कॉन्फ़िगर करता है:placeholderActivityFilterSet
: इसमें गतिविधि फ़िल्टर होते हैं, जो उन गतिविधियों की पहचान करके यह तय करते हैं कि नियम कब लागू किया जाए जिनसे प्लेसहोल्डर गतिविधि जुड़ी है.Intent
: प्लेसहोल्डर गतिविधि के लॉन्च के बारे में बताता है.setDefaultSplitAttributes()
: यह नियम पर लेआउट एट्रिब्यूट लागू करता है.setMinWidthDp()
: डिसप्ले की कम से कम चौड़ाई (डेंसिटी-इंडिपेंडेंट पिक्सल, डीपी में) सेट करता है, ताकि स्प्लिट किया जा सके.setMinSmallestWidthDp()
: यह डिवाइस के ओरिएंटेशन के बावजूद, स्प्लिट स्क्रीन की सुविधा देने के लिए, डिसप्ले के दो डाइमेंशन में से छोटे डाइमेंशन के लिए, कम से कम वैल्यू (dp में) सेट करता है.setMaxAspectRatioInPortrait()
: पोर्ट्रेट ओरिएंटेशन में, डिसप्ले का ज़्यादा से ज़्यादा आसपेक्ट रेशियो (ऊंचाई:चौड़ाई) सेट करता है. इस आसपेक्ट रेशियो में गतिविधि के अलग-अलग हिस्से दिखाए जाते हैं. ध्यान दें: डिफ़ॉल्ट वैल्यू 1.4 होती है. इसकी वजह से, ज़्यादातर टैबलेट पर टास्क विंडो में पोर्ट्रेट ओरिएंटेशन में गतिविधियां भर जाती हैं.SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
औरsetMaxAspectRatioInLandscape()
लेख भी पढ़ें. लैंडस्केप के लिए डिफ़ॉल्ट वैल्यूALWAYS_ALLOW
है.setFinishPrimaryWithPlaceholder()
: इससे यह तय होता है कि प्लेसहोल्डर गतिविधि पूरी होने का असर, प्राइमरी कंटेनर में मौजूद गतिविधियों पर कैसे पड़ता है. हमेशा से यह पता चलता है कि प्लेसहोल्डर के खत्म होने पर, सिस्टम को हमेशा प्राइमरी कंटेनर में मौजूद गतिविधियों को खत्म करना चाहिए (गतिविधियां खत्म करें देखें).setSticky()
: यह तय करता है कि प्लेसहोल्डर ऐक्टिविटी, छोटे डिसप्ले पर ऐक्टिविटी स्टैक में सबसे ऊपर दिखेगी या नहीं. ऐसा तब होता है, जब प्लेसहोल्डर पहली बार कम से कम ज़रूरी चौड़ाई वाले स्प्लिट में दिखता है.
WindowManager
RuleController
में नियम जोड़ें:Kotlin
ruleController.addRule(splitPlaceholderRule)
Java
ruleController.addRule(splitPlaceholderRule);
उन गतिविधियों के बारे में बताएं जिन्हें कभी भी स्प्लिट नहीं किया जाना चाहिए:
ऐसी
ActivityFilter
बनाएं जो किसी ऐसी ऐक्टिविटी की पहचान करता हो जिसे हमेशा टास्क के डिसप्ले एरिया में दिखाया जाना चाहिए:Kotlin
val expandedActivityFilter = ActivityFilter( ComponentName(this, ExpandedActivity::class.java), null )
Java
ActivityFilter expandedActivityFilter = new ActivityFilter( new ComponentName(this, ExpandedActivity.class), null );
फ़िल्टर को फ़िल्टर सेट में जोड़ें:
Kotlin
val expandedActivityFilterSet = setOf(expandedActivityFilter)
Java
Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>(); expandedActivityFilterSet.add(expandedActivityFilter);
ActivityRule
बनाएं:Kotlin
val activityRule = ActivityRule.Builder(expandedActivityFilterSet) .setAlwaysExpand(true) .build()
Java
ActivityRule activityRule = new ActivityRule.Builder( expandedActivityFilterSet ).setAlwaysExpand(true) .build();
ActivityRule.Builder
, नियम बनाता और कॉन्फ़िगर करता है:expandedActivityFilterSet
: इसमें गतिविधि फ़िल्टर होते हैं, जो उन गतिविधियों की पहचान करके यह तय करते हैं जिन्हें आपको स्प्लिट से बाहर रखना है. इससे यह तय होता है कि नियम कब लागू किया जाए.setAlwaysExpand()
: इससे यह तय होता है कि गतिविधि, टास्क विंडो को पूरी तरह से भरनी चाहिए या नहीं.
WindowManager
RuleController
में नियम जोड़ें:Kotlin
ruleController.addRule(activityRule)
Java
ruleController.addRule(activityRule);
एक से ज़्यादा ऐप्लिकेशन में एम्बेड करना
Android 13 (एपीआई लेवल 33) और उसके बाद के वर्शन पर, ऐप्लिकेशन दूसरे ऐप्लिकेशन की ऐक्टिविटी एम्बेड कर सकते हैं. क्रॉस-ऐप्लिकेशन या क्रॉस-UID, ऐक्टिविटी को एम्बेड करने की सुविधा, कई Android ऐप्लिकेशन की ऐक्टिविटी को विज़ुअल इंटिग्रेशन की सुविधा देती है. सिस्टम, होस्ट ऐप्लिकेशन की ऐक्टिविटी और किसी दूसरे ऐप्लिकेशन की एम्बेड की गई ऐक्टिविटी को स्क्रीन पर एक साथ या ऊपर और नीचे दिखाता है. यह ठीक वैसा ही है जैसे किसी एक ऐप्लिकेशन की ऐक्टिविटी को एम्बेड करने पर होता है.
उदाहरण के लिए, Settings ऐप्लिकेशन में WallpaperPicker ऐप्लिकेशन से, वॉलपेपर चुनने की गतिविधि को एम्बेड किया जा सकता है:
ट्रस्ट मॉडल
होस्ट प्रोसेस, दूसरे ऐप्लिकेशन की गतिविधियों को एम्बेड कर सकती हैं. साथ ही, एम्बेड की गई गतिविधियों के प्रज़ेंटेशन को फिर से तय कर सकती हैं. इसमें साइज़, पोज़िशन, काट-छांट, और पारदर्शिता शामिल है. नुकसान पहुंचाने वाले होस्ट, इस सुविधा का इस्तेमाल करके उपयोगकर्ताओं को गुमराह कर सकते हैं. साथ ही, क्लिक जैकिंग या यूज़र इंटरफ़ेस (यूआई) से जुड़े अन्य हमले कर सकते हैं.
क्रॉस-ऐप्लिकेशन गतिविधि को एम्बेड करने के गलत इस्तेमाल को रोकने के लिए, Android ऐप्लिकेशन को अपनी गतिविधियों को एम्बेड करने की अनुमति देने के लिए ऑप्ट-इन करना होगा. ऐप्लिकेशन, होस्ट को भरोसेमंद या गैर-भरोसेमंद के तौर पर सेट कर सकते हैं.
भरोसेमंद होस्ट
दूसरे ऐप्लिकेशन को आपके ऐप्लिकेशन की गतिविधियों को एम्बेड करने और पूरी तरह से कंट्रोल करने की अनुमति देने के लिए, अपने ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल के <activity>
या <application>
एलिमेंट के android:knownActivityEmbeddingCerts
एट्रिब्यूट में, होस्ट ऐप्लिकेशन का SHA-256 सर्टिफ़िकेट डालें.
android:knownActivityEmbeddingCerts
की वैल्यू को स्ट्रिंग के तौर पर सेट करें:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@string/known_host_certificate_digest"
... />
इसके अलावा, एक से ज़्यादा सर्टिफ़िकेट की जानकारी देने के लिए, स्ट्रिंग की कैटगरी का इस्तेमाल करें:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@array/known_host_certificate_digests"
... />
जो इस तरह के संसाधन का रेफ़रंस देता है:
<resources>
<string-array name="known_host_certificate_digests">
<item>cert1</item>
<item>cert2</item>
...
</string-array>
</resources>
ऐप्लिकेशन के मालिक, Gradle
signingReport
टास्क चलाकर SHA सर्टिफ़िकेट का डाइजेस्ट पा सकते हैं. सर्टिफ़िकेट का डाइजेस्ट, SHA-256 फ़िंगरप्रिंट होता है. इसमें कोलन नहीं होते. ज़्यादा जानकारी के लिए, हस्ताक्षर करने की रिपोर्ट चलाना और
अपने क्लाइंट की पुष्टि करना लेख पढ़ें.
भरोसेमंद नहीं हैं
किसी भी ऐप्लिकेशन को आपके ऐप्लिकेशन की गतिविधियों को एम्बेड करने और उनके प्रज़ेंटेशन को कंट्रोल करने की अनुमति देने के लिए, ऐप्लिकेशन मेनिफ़ेस्ट में <activity>
या <application>
एलिमेंट में android:allowUntrustedActivityEmbedding
एट्रिब्यूट की जानकारी दें. उदाहरण के लिए:
<activity
android:name=".MyEmbeddableActivity"
android:allowUntrustedActivityEmbedding="true"
... />
इस एट्रिब्यूट की डिफ़ॉल्ट वैल्यू 'गलत' होती है. इससे, अलग-अलग ऐप्लिकेशन में गतिविधि को एम्बेड करने से रोका जाता है.
पसंद के मुताबिक पुष्टि करने की सुविधा
अविश्वसनीय गतिविधि को एम्बेड करने से जुड़े जोखिमों को कम करने के लिए, पुष्टि करने का कोई कस्टम तरीका बनाएं. इससे होस्ट की पहचान की पुष्टि की जा सकेगी. अगर आपको होस्ट के सर्टिफ़िकेट की जानकारी है, तो पुष्टि करने के लिए androidx.security.app.authenticator
लाइब्रेरी का इस्तेमाल करें. अगर होस्ट आपकी गतिविधि को एम्बेड करने के बाद पुष्टि करता है, तो असल कॉन्टेंट दिखाया जा सकता है. अगर ऐसा नहीं है, तो उपयोगकर्ता को बताएं कि कार्रवाई की अनुमति नहीं है और कॉन्टेंट को ब्लॉक करें.
यह पता करने के लिए कि कोई होस्ट आपकी गतिविधि को एम्बेड कर रहा है या नहीं, Jetpack WindowManager लाइब्रेरी के ActivityEmbeddingController#isActivityEmbedded()
तरीके का इस्तेमाल करें. उदाहरण के लिए:
Kotlin
fun isActivityEmbedded(activity: Activity): Boolean { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity) }
Java
boolean isActivityEmbedded(Activity activity) { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity); }
साइज़ की कम से कम सीमा
Android सिस्टम, एम्बेड की गई गतिविधियों पर, ऐप्लिकेशन के मेनिफ़ेस्ट <layout>
एलिमेंट में बताई गई कम से कम ऊंचाई और चौड़ाई लागू करता है. अगर किसी ऐप्लिकेशन में, कम से कम ऊंचाई और चौड़ाई की जानकारी नहीं दी गई है, तो सिस्टम की डिफ़ॉल्ट वैल्यू लागू होती हैं (sw220dp
).
अगर होस्ट, एम्बेड किए गए कंटेनर का साइज़, कम से कम साइज़ से छोटा करने की कोशिश करता है, तो एम्बेड किया गया कंटेनर, टास्क के पूरे बाउंड को कवर करने के लिए बड़ा हो जाता है.
<activity-alias>
भरोसेमंद या गैर-भरोसेमंद गतिविधि को एम्बेड करने के लिए, <activity-alias>
एलिमेंट के साथ काम करने के लिए, android:knownActivityEmbeddingCerts
या android:allowUntrustedActivityEmbedding
को आलियास के बजाय टारगेट गतिविधि पर लागू किया जाना चाहिए. सिस्टम सर्वर पर सुरक्षा की पुष्टि करने वाली नीति, टारगेट पर सेट किए गए फ़्लैग पर आधारित होती है, न कि किसी दूसरे नाम पर.
होस्ट किया गया ऐप्लिकेशन
होस्ट ऐप्लिकेशन, क्रॉस-ऐप्लिकेशन गतिविधि को उसी तरह एम्बेड करते हैं जिस तरह वे एक ऐप्लिकेशन की गतिविधि को एम्बेड करते हैं. SplitPairRule
और
SplitPairFilter
या ActivityRule
और ActivityFilter
ऑब्जेक्ट, एम्बेड की गई गतिविधियों और टास्क विंडो के स्प्लिट के बारे में बताते हैं. स्प्लिट नियमों को एक्सएमएल में स्टैटिक तौर पर या Jetpack WindowManager API कॉल का इस्तेमाल करके, रनटाइम के दौरान तय किया जाता है.
अगर कोई होस्ट ऐप्लिकेशन ऐसी गतिविधि को एम्बेड करने की कोशिश करता है जिसने क्रॉस-ऐप्लिकेशन एम्बेड करने की सुविधा के लिए ऑप्ट इन नहीं किया है, तो गतिविधि पूरे टास्क के बाउंड में शामिल हो जाती है. इसलिए, होस्ट ऐप्लिकेशन को यह पता होना चाहिए कि टारगेट गतिविधियां, क्रॉस-ऐप्लिकेशन एम्बेड करने की अनुमति देती हैं या नहीं.
अगर एम्बेड की गई कोई गतिविधि, उसी टास्क में नई गतिविधि शुरू करती है और नई गतिविधि ने क्रॉस-ऐप्लिकेशन एम्बेड करने के लिए ऑप्ट-इन नहीं किया है, तो गतिविधि, एम्बेड किए गए कंटेनर में गतिविधि को ओवरले करने के बजाय, पूरे टास्क के बाउंड पर कब्जा कर लेती है.
होस्ट ऐप्लिकेशन, अपनी गतिविधियों को बिना किसी पाबंदी के एम्बेड कर सकता है. हालांकि, ऐसा तब ही किया जा सकता है, जब गतिविधियां एक ही टास्क में लॉन्च हों.
स्प्लिट के उदाहरण
फ़ुल स्क्रीन मोड से स्प्लिट स्क्रीन मोड पर स्विच करना
इसके लिए, कोड में बदलाव करने की ज़रूरत नहीं होती. स्प्लिट के लिए कॉन्फ़िगरेशन को स्टैटिक तौर पर या रनटाइम पर तय किया जा सकता है. इसके बाद, किसी भी अतिरिक्त पैरामीटर के बिना Context#startActivity()
को कॉल किया जा सकता है.
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
डिफ़ॉल्ट रूप से बांटना
जब किसी ऐप्लिकेशन के लैंडिंग पेज को बड़ी स्क्रीन पर दो कंटेनर में बांटा जाता है, तो उपयोगकर्ता अनुभव तब सबसे अच्छा होता है, जब दोनों गतिविधियां एक साथ बनाई और दिखाई जाती हैं. हालांकि, हो सकता है कि स्प्लिट के सेकंडरी कंटेनर के लिए कॉन्टेंट तब तक उपलब्ध न हो, जब तक उपयोगकर्ता प्राइमरी कंटेनर में मौजूद ऐक्टिविटी से इंटरैक्ट न कर ले. उदाहरण के लिए, जब उपयोगकर्ता नेविगेशन मेन्यू से कोई आइटम चुन ले. प्लेसहोल्डर गतिविधि, तब तक खाली जगह को भर सकती है, जब तक कि स्प्लिट के सेकंडरी कंटेनर में कॉन्टेंट नहीं दिखता. ज़्यादा जानकारी के लिए, प्लेसहोल्डर सेक्शन देखें.
प्लेसहोल्डर के साथ स्प्लिट बनाने के लिए, प्लेसहोल्डर बनाएं और उसे मुख्य गतिविधि से असोसिएट करें:
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity">
<ActivityFilter
window:activityName=".MainActivity"/>
</SplitPlaceholderRule>
डीप लिंक का बंटवारा
जब किसी ऐप्लिकेशन को इंटेंट मिलता है, तो टारगेट ऐक्टिविटी को ऐक्टिविटी स्प्लिट के दूसरे हिस्से के तौर पर दिखाया जा सकता है. उदाहरण के लिए, सूची में मौजूद किसी आइटम की जानकारी वाली ज़्यादा जानकारी वाली स्क्रीन दिखाने का अनुरोध. छोटे डिसप्ले पर, ज़्यादा जानकारी, टास्क की पूरी विंडो में दिखती है. वहीं, बड़े डिवाइसों पर, सूची के बगल में दिखती है.
लॉन्च का अनुरोध, मुख्य गतिविधि पर भेजा जाना चाहिए. साथ ही, टारगेट की जानकारी वाली गतिविधि को स्प्लिट में लॉन्च किया जाना चाहिए. सिस्टम, डिसप्ले की उपलब्ध चौड़ाई के आधार पर, अपने-आप सही प्रज़ेंटेशन चुनता है. जैसे, स्टैक किया गया या एक साथ दिखने वाला.
Kotlin
override fun onCreate(savedInstanceState Bundle?) { . . . RuleController.getInstance(this) .addRule(SplitPairRule.Builder(filterSet).build()) startActivity(Intent(this, DetailActivity::class.java)) }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . RuleController.getInstance(this) .addRule(new SplitPairRule.Builder(filterSet).build()); startActivity(new Intent(this, DetailActivity.class)); }
हो सकता है कि बैक नेविगेशन स्टैक में, उपयोगकर्ता के लिए सिर्फ़ डीप लिंक डेस्टिनेशन उपलब्ध हो. साथ ही, हो सकता है कि आप ज़्यादा जानकारी वाली गतिविधि को खारिज करके, सिर्फ़ मुख्य गतिविधि को छोड़ना चाहें:
इसके बजाय, finishPrimaryWithSecondary
एट्रिब्यूट का इस्तेमाल करके, दोनों गतिविधियों को एक साथ पूरा किया जा सकता है:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".ListActivity"
window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>
कॉन्फ़िगरेशन एट्रिब्यूट सेक्शन देखें.
अलग-अलग कंटेनर में कई गतिविधियां
स्प्लिट कंटेनर में कई गतिविधियों को स्टैक करने से, उपयोगकर्ता ज़्यादा जानकारी वाला कॉन्टेंट ऐक्सेस कर पाते हैं. उदाहरण के लिए, सूची-जानकारी के बंटवारे के साथ, उपयोगकर्ता को किसी उप-जानकारी वाले सेक्शन में जाने की ज़रूरत पड़ सकती है, लेकिन प्राइमरी गतिविधि को बरकरार रखना होगा:
Kotlin
class DetailActivity { . . . fun onOpenSubDetail() { startActivity(Intent(this, SubDetailActivity::class.java)) } }
Java
public class DetailActivity { . . . void onOpenSubDetail() { startActivity(new Intent(this, SubDetailActivity.class)); } }
ज़्यादा जानकारी वाली गतिविधि को ज़्यादा जानकारी वाली गतिविधि के ऊपर रखा जाता है, ताकि वह छिपी रहे:
इसके बाद, उपयोगकर्ता स्टैक पर वापस नेविगेट करके, जानकारी के पिछले लेवल पर वापस जा सकता है:
जब एक ही सेकंडरी कंटेनर में मौजूद किसी ऐक्टिविटी से ऐक्टिविटी शुरू की जाती हैं, तो डिफ़ॉल्ट रूप से ऐक्टिविटी एक-दूसरे के ऊपर स्टैक हो जाती हैं. किसी ऐक्टिव स्प्लिट में प्राइमरी कंटेनर से लॉन्च की गई गतिविधियां, ऐक्टिविटी स्टैक में सबसे ऊपर मौजूद सेकंडरी कंटेनर में भी दिखती हैं.
नए टास्क में गतिविधियां
जब स्प्लिट टास्क विंडो में मौजूद गतिविधियां, किसी नए टास्क में गतिविधियां शुरू करती हैं, तो नया टास्क उस टास्क से अलग होता है जिसमें स्प्लिट शामिल होता है और उसे पूरी विंडो में दिखाया जाता है. हाल ही में देखे गए आइटम की स्क्रीन पर दो टास्क दिखते हैं: स्प्लिट स्क्रीन पर मौजूद टास्क और नया टास्क.
गतिविधि बदलना
सेकंडरी कंटेनर स्टैक में ऐक्टिविटी बदली जा सकती हैं. उदाहरण के लिए, जब प्राइमरी ऐक्टिविटी का इस्तेमाल टॉप-लेवल नेविगेशन के लिए किया जाता है और सेकंडरी ऐक्टिविटी को चुना गया डेस्टिनेशन माना जाता है. टॉप-लेवल नेविगेशन से चुने गए हर विकल्प से, सेकंडरी कंटेनर में एक नई गतिविधि शुरू होनी चाहिए. साथ ही, पहले से मौजूद गतिविधि या गतिविधियों को हटाना चाहिए.
अगर नेविगेशन के विकल्प बदलने पर, ऐप्लिकेशन सेकंडरी कंटेनर में गतिविधि पूरी नहीं करता है, तो स्प्लिट स्क्रीन को छोटा करने पर (डिवाइस को फ़ोल्ड करने पर) बैक नेविगेशन भ्रमित कर सकता है. उदाहरण के लिए, अगर आपके पास मुख्य पैनल में एक मेन्यू है और स्क्रीन A और B, सेकंडरी पैनल में स्टैक की गई हैं, तो जब उपयोगकर्ता फ़ोन को फ़ोल्ड करता है, तो B, A के ऊपर और A, मेन्यू के ऊपर होता है. जब उपयोगकर्ता B से वापस आता है, तो मेन्यू के बजाय A दिखता है.
ऐसे मामलों में, स्क्रीन A को बैक स्टैक से हटाना होगा.
किसी मौजूदा स्प्लिट के ऊपर, नए कंटेनर में साइड में लॉन्च करने पर, डिफ़ॉल्ट रूप से नए सेकंडरी कंटेनर सबसे ऊपर दिखते हैं और पुराने कंटेनर बैक स्टैक में बने रहते हैं. clearTop
की मदद से, पिछले सेकंडरी कंटेनर को मिटाने और सामान्य तौर पर नई गतिविधियां लॉन्च करने के लिए, स्प्लिट को कॉन्फ़िगर किया जा सकता है.
<SplitPairRule
window:clearTop="true">
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenA"/>
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>
Kotlin
class MenuActivity { . . . fun onMenuItemSelected(selectedMenuItem: Int) { startActivity(Intent(this, classForItem(selectedMenuItem))) } }
Java
public class MenuActivity { . . . void onMenuItemSelected(int selectedMenuItem) { startActivity(new Intent(this, classForItem(selectedMenuItem))); } }
इसके अलावा, एक ही सेकंडरी गतिविधि का इस्तेमाल करें और प्राइमरी (मेन्यू) गतिविधि से नए इंटेंट भेजें. ये इंटेंट उसी इंस्टेंस को रिज़ॉल्व करते हैं, लेकिन सेकंडरी कंटेनर में स्टेटस या यूज़र इंटरफ़ेस (यूआई) अपडेट को ट्रिगर करते हैं.
एक से ज़्यादा स्प्लिट
ऐप्लिकेशन, साइड में अन्य गतिविधियां लॉन्च करके, कई लेवल का डीप नेविगेशन उपलब्ध करा सकते हैं.
जब किसी सेकंडरी कंटेनर में मौजूद कोई ऐक्टिविटी, साइड में नई ऐक्टिविटी लॉन्च करती है, तो मौजूदा स्प्लिट के ऊपर एक नया स्प्लिट बन जाता है.
बैक स्टैक में वे सभी गतिविधियां होती हैं जो पहले खोली गई थीं. इसलिए, उपयोगकर्ता C को पूरा करने के बाद, A/B स्प्लिट पर नेविगेट कर सकते हैं.
नया स्प्लिट बनाने के लिए, मौजूदा सेकंडरी कंटेनर के बगल में नई गतिविधि लॉन्च करें. A/B और B/C, दोनों स्प्लिट के लिए कॉन्फ़िगरेशन तय करें और B से गतिविधि C को सामान्य रूप से लॉन्च करें:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
<SplitPairFilter
window:primaryActivityName=".B"
window:secondaryActivityName=".C"/>
</SplitPairRule>
Kotlin
class B { . . . fun onOpenC() { startActivity(Intent(this, C::class.java)) } }
Java
public class B { . . . void onOpenC() { startActivity(new Intent(this, C.class)); } }
स्प्लिट स्क्रीन की स्थिति में होने वाले बदलावों पर प्रतिक्रिया देना
किसी ऐप्लिकेशन की अलग-अलग गतिविधियों में, एक जैसे फ़ंक्शन करने वाले यूज़र इंटरफ़ेस (यूआई) एलिमेंट हो सकते हैं. उदाहरण के लिए, खाते की सेटिंग वाली विंडो खोलने वाला कंट्रोल.
अगर दो गतिविधियों में एक ही यूज़र इंटरफ़ेस (यूआई) एलिमेंट है और वे स्प्लिट में हैं, तो दोनों गतिविधियों में एलिमेंट दिखाना ग़ैर-ज़रूरी है. साथ ही, इससे शायद भ्रम भी हो सकता है.
यह जानने के लिए कि गतिविधियां कब अलग-अलग होती हैं, SplitController.splitInfoList
फ़्लो देखें या स्प्लिट स्टेटस में होने वाले बदलावों के लिए, SplitControllerCallbackAdapter
के साथ किसी लिसनर को रजिस्टर करें. इसके बाद, यूज़र इंटरफ़ेस (यूआई) को इनके हिसाब से अडजस्ट करें:
Kotlin
val layout = layoutInflater.inflate(R.layout.activity_main, null) val view = layout.findViewById<View>(R.id.infoButton) lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { splitController.splitInfoList(this@SplitDeviceActivity) // The activity instance. .collect { list -> view.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE } } }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . new SplitControllerCallbackAdapter(SplitController.getInstance(this)) .addSplitListener( this, Runnable::run, splitInfoList -> { View layout = getLayoutInflater().inflate(R.layout.activity_main, null); layout.findViewById(R.id.infoButton).setVisibility( splitInfoList.isEmpty() ? View.VISIBLE : View.GONE); }); }
कोरुटिन को लाइफ़साइकल की किसी भी स्थिति में लॉन्च किया जा सकता है. हालांकि, आम तौर पर इन्हें संसाधनों को बचाने के लिए, STARTED
स्थिति में लॉन्च किया जाता है. ज़्यादा जानकारी के लिए, लाइफ़साइकल के बारे में जानकारी देने वाले कॉम्पोनेंट के साथ Kotlin कोरुटिन का इस्तेमाल करना लेख पढ़ें.
कॉलबैक, लाइफ़साइकल की किसी भी स्थिति में किए जा सकते हैं. इनमें, गतिविधि के बंद होने की स्थिति भी शामिल है. आम तौर पर, दर्शकों को onStart()
में रजिस्टर होना चाहिए और onStop()
में रजिस्टर नहीं होना चाहिए.
फ़ुल-विंडो मोडल
कुछ गतिविधियां, उपयोगकर्ताओं को ऐप्लिकेशन के साथ तब तक इंटरैक्ट करने से ब्लॉक करती हैं, जब तक कोई खास कार्रवाई नहीं की जाती. उदाहरण के लिए, लॉगिन स्क्रीन गतिविधि, नीति की पुष्टि करने वाली स्क्रीन या गड़बड़ी का मैसेज. मोडल गतिविधियों को स्प्लिट में दिखने से रोका जाना चाहिए.
'बड़ा करें' कॉन्फ़िगरेशन का इस्तेमाल करके, किसी गतिविधि को हमेशा टास्क विंडो में भरने के लिए मजबूर किया जा सकता है:
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".FullWidthActivity"/>
</ActivityRule>
गतिविधियां पूरी करना
उपयोगकर्ता, स्प्लिट स्क्रीन के दोनों हिस्सों पर की जा रही गतिविधियों को खत्म कर सकते हैं. इसके लिए, उन्हें डिसप्ले के किनारे से स्वाइप करना होगा:
अगर डिवाइस को जेस्चर नेविगेशन के बजाय, 'वापस जाएं' बटन का इस्तेमाल करने के लिए सेट अप किया गया है, तो इनपुट उस गतिविधि पर भेजा जाता है जिस पर फ़ोकस किया गया है. यह वह गतिविधि होती है जिसे आखिरी बार छुआ गया था या जो आखिरी बार लॉन्च की गई थी.
किसी कंटेनर में सभी गतिविधियां पूरी करने का असर, दूसरे कंटेनर पर पड़ता है. यह असर, स्प्लिट कॉन्फ़िगरेशन पर निर्भर करता है.
कॉन्फ़िगरेशन एट्रिब्यूट
स्प्लिट पेयर के नियम के एट्रिब्यूट तय करके, यह कॉन्फ़िगर किया जा सकता है कि स्प्लिट के एक हिस्से में सभी गतिविधियां पूरी करने से, स्प्लिट के दूसरे हिस्से में गतिविधियों पर क्या असर पड़ता है. ये एट्रिब्यूट हैं:
window:finishPrimaryWithSecondary
— सेकंडरी कंटेनर में सभी गतिविधियां पूरी करने से, प्राइमरी कंटेनर में मौजूद गतिविधियों पर क्या असर पड़ता हैwindow:finishSecondaryWithPrimary
— प्राइमरी कंटेनर में सभी गतिविधियां पूरी करने से, सेकंडरी कंटेनर में मौजूद गतिविधियों पर क्या असर पड़ता है
एट्रिब्यूट की संभावित वैल्यू में ये शामिल हैं:
always
— हमेशा उसी कंटेनर में गतिविधियां पूरी करें जिससे वे जुड़ी हैंnever
— असोसिएट किए गए कंटेनर में गतिविधियां कभी न खत्म करेंadjacent
— जब दो कंटेनर एक-दूसरे के बगल में दिखते हैं, तो उससे जुड़े कंटेनर में गतिविधियां पूरी करें. हालांकि, जब दो कंटेनर स्टैक किए जाते हैं, तो ऐसा न करें
उदाहरण के लिए:
<SplitPairRule
<!-- Do not finish primary container activities when all secondary container activities finish. -->
window:finishPrimaryWithSecondary="never"
<!-- Finish secondary container activities when all primary container activities finish. -->
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
डिफ़ॉल्ट कॉन्फ़िगरेशन
जब स्प्लिट स्क्रीन के किसी कंटेनर में मौजूद सभी गतिविधियां पूरी हो जाती हैं, तो बाकी कंटेनर पूरी विंडो पर दिखने लगता है:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
साथ मिलकर गतिविधियां पूरी करना
सेकंडरी कंटेनर में सभी गतिविधियां पूरी होने पर, प्राइमरी कंटेनर में गतिविधियां अपने-आप खत्म हो जाएं:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
प्राइमरी कंटेनर में सभी गतिविधियां पूरी होने पर, सेकंडरी कंटेनर में गतिविधियां अपने-आप पूरी हो जाएं:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
प्राइमरी या सेकंडरी कंटेनर में सभी गतिविधियां खत्म होने पर, गतिविधियों को एक साथ खत्म करना:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
कंटेनर में कई गतिविधियां पूरी करना
अगर स्प्लिट कंटेनर में कई गतिविधियां स्टैक की गई हैं, तो स्टैक में सबसे नीचे मौजूद गतिविधि को पूरा करने पर, सबसे ऊपर मौजूद गतिविधियां अपने-आप पूरी नहीं होतीं.
उदाहरण के लिए, अगर सेकंडरी कंटेनर में दो गतिविधियां हैं, तो B के ऊपर C:
और स्प्लिट का कॉन्फ़िगरेशन, गतिविधियों A और B के कॉन्फ़िगरेशन से तय होता है:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
सबसे ऊपर मौजूद गतिविधि को पूरा करने पर, स्प्लिट की गई स्क्रीन का क्रम नहीं बदलता.
सेकंडरी कंटेनर की सबसे नीचे (रूट) मौजूद ऐक्टिविटी को पूरा करने पर, उसके ऊपर मौजूद ऐक्टिविटी नहीं हटतीं. इसलिए, स्प्लिट भी बना रहता है.
गतिविधियों को एक साथ खत्म करने के लिए, कोई भी अन्य नियम भी लागू किया जाता है. जैसे, मुख्य गतिविधि के साथ सेकंडरी गतिविधि को खत्म करना:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
अगर स्प्लिट को प्राइमरी और सेकंडरी, दोनों को एक साथ खत्म करने के लिए कॉन्फ़िगर किया गया है, तो:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
रनटाइम के दौरान, स्प्लिट प्रॉपर्टी बदलना
चालू और दिख रहे स्प्लिट की प्रॉपर्टी नहीं बदली जा सकतीं. स्प्लिट के नियमों में बदलाव करने से, अन्य ऐक्टिविटी लॉन्च और नए कंटेनर पर असर पड़ता है. हालांकि, मौजूदा और चालू स्प्लिट पर असर नहीं पड़ता.
चालू स्प्लिट की प्रॉपर्टी बदलने के लिए, स्प्लिट में साइड गतिविधि या गतिविधियों को पूरा करें और नए कॉन्फ़िगरेशन के साथ साइड को फिर से लॉन्च करें.
डाइनैमिक स्प्लिट प्रॉपर्टी
Android 15 (एपीआई लेवल 35) और इसके बाद के वर्शन, Jetpack WindowManager 1.4 और इसके बाद के वर्शन के साथ काम करते हैं. इनमें डाइनैमिक सुविधाएं होती हैं, जिनकी मदद से गतिविधि को एम्बेड करने वाले स्प्लिट को कॉन्फ़िगर किया जा सकता है. इनमें ये सुविधाएं शामिल हैं:
- पैनल का साइज़ बढ़ाना: इंटरैक्टिव और खींचकर छोड़े जा सकने वाले डिवाइडर की मदद से, उपयोगकर्ता स्प्लिट प्रज़ेंटेशन में पैनल का साइज़ बदल सकते हैं.
- गतिविधि स्टैक को पिन करना: उपयोगकर्ता एक कंटेनर में कॉन्टेंट को पिन कर सकते हैं और एक कंटेनर के नेविगेशन को दूसरे कंटेनर के नेविगेशन से अलग कर सकते हैं.
- डायलॉग बॉक्स को फ़ुल स्क्रीन में धुंधला करना: डायलॉग बॉक्स दिखाते समय, ऐप्लिकेशन यह तय कर सकते हैं कि पूरी टास्क विंडो को धुंधला करना है या सिर्फ़ उस कंटेनर को जिसने डायलॉग बॉक्स खोला है.
पैनल को बड़ा करना
पैनल को बड़ा करने की सुविधा की मदद से, उपयोगकर्ता दो पैनल वाले लेआउट में, दोनों गतिविधियों के लिए स्क्रीन पर तय किए गए स्पेस में बदलाव कर सकते हैं.
विंडो डिवाइडर के दिखने का तरीका पसंद के मुताबिक बनाने और डिवाइडर की खींची-छुड़ाई जा सकने वाली रेंज सेट करने के लिए, यह तरीका अपनाएं:
DividerAttributes
का इंस्टेंस बनानाडिवाइडर एट्रिब्यूट को पसंद के मुताबिक बनाएं:
color
: पैनल के बीच में खींचकर छोड़े जा सकने वाले सेपरेटर का रंग.widthDp
: पैनल के बीच में मौजूद, खींचे और छोड़े जा सकने वाले सेपरेटर की चौड़ाई. डिवाइस के सिस्टम को डिवाइडर की चौड़ाई तय करने की अनुमति देने के लिए, इसकी वैल्यू कोWIDTH_SYSTEM_DEFAULT
पर सेट करें.खींचने की सीमा: स्क्रीन पर, दोनों पैनल में से किसी एक पैनल का कम से कम प्रतिशत. यह वैल्यू 0.33 से 0.66 के बीच हो सकती है.
DRAG_RANGE_SYSTEM_DEFAULT
पर सेट करें, ताकि सिस्टम यह तय कर सके कि आइटम को कितनी दूर तक खींचा और छोड़ा जाए.
Kotlin
val splitAttributesBuilder: SplitAttributes.Builder = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) if (WindowSdkExtensions.getInstance().extensionVersion >= 6) { splitAttributesBuilder.setDividerAttributes( DividerAttributes.DraggableDividerAttributes.Builder() .setColor(getColor(context, R.color.divider_color)) .setWidthDp(4) .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT) .build() ) } val splitAttributes: SplitAttributes = splitAttributesBuilder.build()
Java
SplitAttributes.Builder splitAttributesBuilder = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT); if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) { splitAttributesBuilder.setDividerAttributes( new DividerAttributes.DraggableDividerAttributes.Builder() .setColor(ContextCompat.getColor(context, R.color.divider_color)) .setWidthDp(4) .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT) .build() ); } SplitAttributes splitAttributes = splitAttributesBuilder.build();
गतिविधि स्टैक को पिन करना
ऐक्टिविटी स्टैक को पिन करने की सुविधा की मदद से, उपयोगकर्ता स्प्लिट विंडो में से किसी एक विंडो को पिन कर सकते हैं. इससे, जब उपयोगकर्ता दूसरी विंडो पर जाते हैं, तब ऐक्टिविटी पहले जैसी ही रहती है. गतिविधि स्टैक को पिन करने से, एक साथ कई काम करने का बेहतर अनुभव मिलता है.
अपने ऐप्लिकेशन में ऐक्टिविटी स्टैक को पिन करने की सुविधा चालू करने के लिए, यह तरीका अपनाएं:
जिस गतिविधि को पिन करना है उसकी लेआउट फ़ाइल में बटन जोड़ें. उदाहरण के लिए, सूची‑जानकारी वाले लेआउट की गतिविधि की जानकारी:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/detailActivity" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" tools:context=".DetailActivity"> <TextView android:id="@+id/textViewItemDetail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="36sp" android:textColor="@color/obsidian" app:layout_constraintBottom_toTopOf="@id/pinButton" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/pinButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pin_this_activity" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textViewItemDetail"/> </androidx.constraintlayout.widget.ConstraintLayout>
ऐक्टिविटी के
onCreate()
तरीके में, बटन पर onclick लिसनर सेट करें:Kotlin
pinButton = findViewById(R.id.pinButton) pinButton.setOnClickListener { val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.66f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build() val pinSplitRule = SplitPinRule.Builder() .setSticky(true) .setDefaultSplitAttributes(splitAttributes) .build() SplitController.getInstance(applicationContext).pinTopActivityStack(taskId, pinSplitRule) }
Java
Button pinButton = findViewById(R.id.pinButton); pinButton.setOnClickListener( (view) => { SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.66f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build(); SplitPinRule pinSplitRule = new SplitPinRule.Builder() .setSticky(true) .setDefaultSplitAttributes(splitAttributes) .build(); SplitController.getInstance(getApplicationContext()).pinTopActivityStack(getTaskId(), pinSplitRule); });
डायलॉग बॉक्स को फ़ुल-स्क्रीन मोड में धुंधला करना
आम तौर पर, किसी डायलॉग पर ध्यान खींचने के लिए, गतिविधियां अपने डिसप्ले को मंद कर देती हैं. गतिविधि को एम्बेड करने पर, ड्यूअल पैनल वाले डिसप्ले के दोनों पैनल मंद होने चाहिए. ऐसा इसलिए, ताकि यूज़र इंटरफ़ेस (यूआई) का एक जैसा अनुभव मिल सके.
WindowManager 1.4 और उसके बाद के वर्शन में, डायलॉग बॉक्स खुलने पर ऐप्लिकेशन की पूरी विंडो डिफ़ॉल्ट रूप से धुंधली हो जाती है (EmbeddingConfiguration.DimAreaBehavior.ON_TASK
देखें).
डायलॉग बॉक्स खोलने वाली गतिविधि के कंटेनर को सिर्फ़ धुंधला करने के लिए, EmbeddingConfiguration.DimAreaBehavior.ON_ACTIVITY_STACK
का इस्तेमाल करें.
स्प्लिट विंडो से किसी गतिविधि को फ़ुल विंडो में ले जाना
एक नया कॉन्फ़िगरेशन बनाएं, जो साइड गतिविधि की पूरी विंडो दिखाता हो. इसके बाद, उस इंटेंट के साथ गतिविधि को फिर से लॉन्च करें जो उसी इंस्टेंस को हल करता हो.
रनटाइम के दौरान, स्प्लिट की सुविधा के काम करने की जांच करना
गतिविधि को एम्बेड करने की सुविधा, Android 12L (एपीआई लेवल 32) और इसके बाद के वर्शन पर काम करती है. हालांकि, यह सुविधा प्लैटफ़ॉर्म के पुराने वर्शन पर चलने वाले कुछ डिवाइसों पर भी उपलब्ध है. रनटाइम के दौरान, सुविधा की उपलब्धता देखने के लिए, SplitController.splitSupportStatus
प्रॉपर्टी या SplitController.getSplitSupportStatus()
तरीके का इस्तेमाल करें:
Kotlin
if (SplitController.getInstance(this).splitSupportStatus == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
Java
if (SplitController.getInstance(this).getSplitSupportStatus() == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
अगर स्प्लिट की सुविधा काम नहीं करती है, तो गतिविधियां गतिविधि स्टैक के ऊपर लॉन्च की जाती हैं. ऐसा, गतिविधि को एम्बेड न करने वाले मॉडल के हिसाब से किया जाता है.
सिस्टम ओवरराइड को रोकना
Android डिवाइस बनाने वाली कंपनियां (ओरिजनल इक्विपमेंट मैन्युफ़ैक्चरर या OEM), डिवाइस सिस्टम के फ़ंक्शन के तौर पर गतिविधि को एम्बेड करने की सुविधा लागू कर सकती हैं. सिस्टम, कई गतिविधियों वाले ऐप्लिकेशन के लिए स्प्लिट नियम तय करता है. इससे, ऐप्लिकेशन के विंडो व्यवहार को बदला जा सकता है. सिस्टम की ओर से बदलाव करने पर, एक से ज़्यादा गतिविधियों वाले ऐप्लिकेशन, सिस्टम के तय किए गए गतिविधि एम्बेड करने वाले मोड में चलाए जाते हैं.
सिस्टम की गतिविधि को एम्बेड करने से, ऐप्लिकेशन में कोई बदलाव किए बिना, list-detail जैसे कई पैनल वाले लेआउट की मदद से, ऐप्लिकेशन को बेहतर तरीके से दिखाया जा सकता है. हालांकि, सिस्टम की गतिविधि को एम्बेड करने से, ऐप्लिकेशन के लेआउट गलत हो सकते हैं, गड़बड़ियां हो सकती हैं या ऐप्लिकेशन की गतिविधि को एम्बेड करने की सुविधा के साथ समस्याएं आ सकती हैं.
आपका ऐप्लिकेशन, ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल में प्रॉपर्टी सेट करके, सिस्टम गतिविधि को एम्बेड होने से रोक सकता है या उसे अनुमति दे सकता है. उदाहरण के लिए:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<property
android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
android:value="true|false" />
</application>
</manifest>
प्रॉपर्टी का नाम, Jetpack WindowManager WindowProperties
ऑब्जेक्ट में तय किया जाता है. अगर आपका ऐप्लिकेशन गतिविधि को एम्बेड करने की सुविधा लागू करता है या आपको सिस्टम को अपने ऐप्लिकेशन पर गतिविधि को एम्बेड करने के नियम लागू करने से रोकना है, तो वैल्यू को false
पर सेट करें. सिस्टम को अपने ऐप्लिकेशन पर, सिस्टम के तय किए गए गतिविधि को एम्बेड करने के नियम लागू करने की अनुमति देने के लिए, वैल्यू को true
पर सेट करें.
सीमाएं, पाबंदियां, और सावधानियां
- टास्क के होस्ट ऐप्लिकेशन, यानी टास्क में रूट गतिविधि के मालिक के पास ही, टास्क में अन्य गतिविधियों को व्यवस्थित करने और उन्हें एम्बेड करने का विकल्प होता है. अगर एम्बेड करने और स्प्लिट करने की सुविधा देने वाली गतिविधियां, किसी दूसरे ऐप्लिकेशन से जुड़े टास्क में चलती हैं, तो उन गतिविधियों के लिए एम्बेड करने और स्प्लिट करने की सुविधा काम नहीं करेगी.
- गतिविधियों को सिर्फ़ एक टास्क में व्यवस्थित किया जा सकता है. किसी नई गतिविधि को नए टास्क में लॉन्च करने पर, वह हमेशा किसी भी मौजूदा स्प्लिट के बाहर, नई और बड़ी विंडो में खुलती है.
- सिर्फ़ एक ही प्रोसेस की गतिविधियों को व्यवस्थित करके, अलग-अलग ग्रुप में बांटा जा सकता है.
SplitInfo
कॉलबैक सिर्फ़ एक ही प्रोसेस से जुड़ी गतिविधियों की जानकारी देता है. ऐसा इसलिए, क्योंकि अलग-अलग प्रोसेस में होने वाली गतिविधियों के बारे में जानने का कोई तरीका नहीं है. - हर जोड़ी या एकल गतिविधि का नियम, सिर्फ़ उन गतिविधियों के लॉन्च पर लागू होता है जो नियम के रजिस्टर होने के बाद शुरू होती हैं. फ़िलहाल, मौजूदा स्प्लिट या उनकी विज़ुअल प्रॉपर्टी को अपडेट करने का कोई तरीका नहीं है.
- स्प्लिट पेयर फ़िल्टर कॉन्फ़िगरेशन, पूरी तरह से गतिविधियां लॉन्च करते समय इस्तेमाल किए गए इंटेंट से मेल खाना चाहिए. मैचिंग तब होती है, जब ऐप्लिकेशन प्रोसेस से कोई नई गतिविधि शुरू की जाती है. इसलिए, हो सकता है कि उसे उन कॉम्पोनेंट के नामों के बारे में पता न हो जिन्हें सिस्टम प्रोसेस में बाद में हल किया जाता है. ऐसा तब होता है, जब इंप्लिसिट इंटेंट का इस्तेमाल किया जाता है. अगर लॉन्च के समय किसी कॉम्पोनेंट का नाम नहीं पता है, तो उसके बजाय वाइल्डकार्ड ("*/*") का इस्तेमाल किया जा सकता है. साथ ही, इंटेंट ऐक्शन के आधार पर फ़िल्टर किया जा सकता है.
- फ़िलहाल, गतिविधियों को बनाने के बाद, उन्हें कंटेनर के बीच या स्प्लिट में और स्प्लिट से बाहर नहीं ले जाया जा सकता. WindowManager लाइब्रेरी, स्प्लिट सिर्फ़ तब बनाती है, जब मैच करने वाले नियमों के साथ नई गतिविधियां लॉन्च की जाती हैं. साथ ही, स्प्लिट कंटेनर में आखिरी गतिविधि पूरी होने पर, स्प्लिट हटा दिए जाते हैं.
- कॉन्फ़िगरेशन में बदलाव होने पर, गतिविधियों को फिर से लॉन्च किया जा सकता है. इसलिए, जब कोई स्प्लिट बनाया जाता है या हटाया जाता है और गतिविधि के बाउंड में बदलाव होता है, तो गतिविधि के पिछले इंस्टेंस को पूरी तरह से मिटाकर नया इंस्टेंस बनाया जा सकता है. इसलिए, ऐप्लिकेशन डेवलपर को लाइफ़साइकल कॉलबैक से नई गतिविधियां लॉन्च करने जैसी चीज़ों को लेकर सावधानी बरतनी चाहिए.
- गतिविधि को एम्बेड करने की सुविधा के साथ काम करने के लिए, डिवाइसों में विंडो एक्सटेंशन इंटरफ़ेस होना चाहिए. Android 12L (एपीआई लेवल 32) या इसके बाद के वर्शन पर चलने वाले, बड़े स्क्रीन वाले ज़्यादातर डिवाइसों में यह इंटरफ़ेस शामिल होता है. हालांकि, कुछ बड़े स्क्रीन वाले डिवाइसों में विंडो एक्सटेंशन इंटरफ़ेस नहीं होता. ऐसा इसलिए होता है, क्योंकि ये डिवाइस एक से ज़्यादा गतिविधियां नहीं चला सकते. अगर बड़ी स्क्रीन वाले डिवाइस पर मल्टी-विंडो मोड काम नहीं करता है, तो हो सकता है कि उस पर गतिविधि को एम्बेड करने की सुविधा काम न करे.
अन्य संसाधन
- Codelabs:
- विषय से जुड़े ऑनलाइन कोर्स और रेफ़रंस मटीरियल — गतिविधि को एम्बेड करना
- सैंपल ऐप्लिकेशन — activity-embedding