गतिविधि एम्बेड करना

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

पहला डायग्राम. सेटिंग ऐप्लिकेशन, जिसमें एक साथ कई गतिविधियां दिखाई गई हैं.

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

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

छोटी स्क्रीन पर काम करने की सुविधा अपने-आप बनी रहती है. जब आपका ऐप्लिकेशन छोटी स्क्रीन वाले डिवाइस में, गतिविधियों को एक के ऊपर एक रखा जाता है. चालू है बड़ी स्क्रीन, गतिविधियाँ एक साथ दिखेंगी. सिस्टम तय करता है कि आपके बनाए गए कॉन्फ़िगरेशन पर आधारित प्रज़ेंटेशन—कोई ब्रांचिंग लॉजिक नहीं है आवश्यक है.

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

गतिविधि एम्बेड करने की सुविधा, Android 12L वर्शन पर चलने वाले ज़्यादातर बड़ी स्क्रीन वाले डिवाइसों पर काम करती है (एपीआई लेवल 32) और उसके बाद वाले वर्शन.

टास्क विंडो को स्प्लिट करना

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

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

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

दूसरी इमेज. अगल-बगल में मौजूद दो गतिविधियां.

इसके अलावा, पूरी टास्क विंडो में चल रही कोई भी गतिविधि इसके साथ नई गतिविधि लॉन्च करना:

तीसरा डायग्राम. गतिविधि A, गतिविधि B को एक तरफ़ शुरू करती है.

ऐसी गतिविधियां लॉन्च हो सकती हैं जो पहले से ही बंटी हुई हैं और टास्क विंडो शेयर की जा रही हैं अन्य गतिविधियों को पूरा करते हैं:

  • किसी दूसरी गतिविधि के ऊपर बाईं ओर:

    चौथी इमेज. ऐक्टिविटी A, ऐक्टिविटी B के बगल में ऐक्टिविटी C शुरू करती है.
  • साइड की ओर करें और पिछले प्राइमरी को छिपाते हुए स्प्लिट को साइड की तरफ़ शिफ़्ट करें गतिविधि:

    पांचवीं इमेज. गतिविधि B, गतिविधि C को एक तरफ़ शुरू करती है और दो भागों में बंटा होता है.
  • किसी ऐक्टिविटी को सबसे ऊपर लॉन्च करें. इसका मतलब है कि उसी ऐक्टिविटी स्टैक में:

    छठी इमेज. गतिविधि B, गतिविधि C को बिना किसी अतिरिक्त इंटेंट फ़्लैग के शुरू करती है.
  • उसी टास्क में किसी गतिविधि की फ़ुल विंडो लॉन्च करने के लिए:

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

पिछले पेज पर जाने का नेविगेशन

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

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

बटन का इस्तेमाल करने पर, पिछले इवेंट को फ़ोकस की गई पिछली गतिविधि पर भेजा जाता है नेविगेशन.

जेस्चर वाले नेविगेशन के लिए:

  • 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 सेक्शन देखें.

नौवीं इमेज. बाईं से दाईं ओर लेआउट किए गए दो गतिविधि स्प्लिट, लेकिन अलग-अलग स्प्लिट रेशियो के साथ.

प्लेसहोल्डर

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

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

10वीं इमेज. फ़ोल्ड किए जा सकने वाले डिवाइस को फ़ोल्ड और अनफ़ोल्ड करना. प्लेसहोल्डर की गतिविधि पूरी हो जाती है और डिसप्ले साइज़ बदलने पर, उसे फिर से बनाया जाता है.

हालांकि, stickyPlaceholder की विशेषता SplitPlaceholderRule या SplitPlaceholder.Builder का setSticky() तरीका डिफ़ॉल्ट व्यवहार. जब एट्रिब्यूट या तरीके में true की वैल्यू दी जाती है, तो डिसप्ले को दो पैनल वाले डिसप्ले से एक पैनल वाले डिसप्ले में बदलने पर, सिस्टम टास्क विंडो में प्लेसहोल्डर को सबसे ऊपर की गतिविधि के तौर पर दिखाता है. उदाहरण के लिए, स्प्लिट कॉन्फ़िगरेशन देखें.

11वीं इमेज. फ़ोल्ड किए जा सकने वाले डिवाइस को फ़ोल्ड और अनफ़ोल्ड किया जा रहा है. प्लेसहोल्डर गतिविधि स्टिकी है.

विंडो के साइज़ में बदलाव

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

प्लेसहोल्डर गतिविधियां सिर्फ़ तब दिखाई जाती हैं, जब स्प्लिट के लिए डिसप्ले की चौड़ाई काफ़ी हो. छोटी स्क्रीन पर, प्लेसहोल्डर अपने-आप हट जाता है. जब डिसप्ले एरिया फिर से इतना बड़ा हो जाता है कि प्लेसहोल्डर फिर से बन जाता है. (प्लेसहोल्डर सेक्शन देखें.)

गतिविधि को स्टैक किया जा सकता है, क्योंकि WindowManager, सेकंडरी पैनल में मौजूद गतिविधियों को प्राइमरी पैनल में मौजूद गतिविधियों के ऊपर z-क्रम में लगाता है.

दूसरे पैनल में कई गतिविधियां

गतिविधि B बिना किसी अतिरिक्त इंटेंट फ़्लैग के गतिविधि C शुरू करती है:

गतिविधि का बंटवारा, जिसमें गतिविधियां A, B, और C शामिल हैं. साथ ही, C को B के ऊपर स्टैक किया गया है.

नतीजे के तौर पर, एक ही टास्क में ये ज़ेड-ऑर्डर (वे क्रम में) दिखेंगे:

सेकंडरी गतिविधि का स्टैक, जिसमें B के ऊपर गतिविधि C स्टैक की गई है.
          सेकंडरी स्टैक, ऐक्टिविटी A वाले प्राइमरी ऐक्टिविटी स्टैक के ऊपर स्टैक किया गया है.

इसलिए, छोटी टास्क विंडो में, ऐप्लिकेशन एक गतिविधि में सिकुड़ जाता है. इसमें स्टैक के सबसे ऊपर C होता है:

छोटी विंडो में सिर्फ़ गतिविधि C दिख रही है.

छोटी विंडो में वापस जाने पर, एक-दूसरे के ऊपर स्टैक की गई गतिविधियों पर नेविगेट किया जा सकता है.

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

स्टैक किए गए स्प्लिट

गतिविधि B, गतिविधि C को साइड में शुरू करती है और स्प्लिट को साइड में शिफ़्ट करती है:

टास्क की विंडो, जिसमें A और B गतिविधियां हैं. इसके बाद, B और C गतिविधियां दिख रही हैं.

इससे पता चलता है कि एक ही टास्क में, गतिविधियों का ज़ेड-ऑर्डर नीचे दिया गया है:

एक ही स्टैक में गतिविधियां A, B, और C. गतिविधियों को ऊपर से नीचे के क्रम में, इस क्रम में स्टैक किया जाता है: C, B, A.

छोटी टास्क विंडो में, ऐप्लिकेशन एक गतिविधि में सिकुड़ जाता है, जिसमें सबसे ऊपर C होता है:

सिर्फ़ गतिविधि C को दिखाने वाली छोटी विंडो.

फ़िक्स्ड-पोर्ट्रेट ओरिएंटेशन

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

12वीं इमेज. लेटरबॉक्स वाली गतिविधियां: लैंडस्केप डिवाइस पर फ़िक्स्ड-पोर्ट्रेट (बाईं ओर), पोर्ट्रेट डिवाइस पर फ़िक्स्ड-लैंडस्केप (दाईं ओर).

इसी तरह, गतिविधि को एम्बेड करने की सुविधा चालू होने पर, OEM बड़ी स्क्रीन (चौड़ाई ≥ 600dp) पर, लैंडस्केप ओरिएंटेशन में लेटरबॉक्स फ़िक्स्ड-पोर्ट्रेट गतिविधियों के लिए, डिवाइसों को पसंद के मुताबिक बना सकते हैं. जब कोई फ़िक्स्ड-पोर्ट्रेट गतिविधि दूसरी गतिविधि लॉन्च करती है, तो डिवाइस, दो पैनल वाले डिसप्ले में दो गतिविधियों को एक साथ दिखा सकता है.

13वां डायग्राम. फ़िक्स्ड-पोर्ट्रेट ऐक्टिविटी A, साइड में ऐक्टिविटी B शुरू करती है.

हमेशा android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED जोड़ें प्रॉपर्टी को अपनी ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल में लिंक करें, ताकि उन डिवाइस के बारे में जानकारी दी जा सके जिनके साथ आपका ऐप्लिकेशन काम करता है गतिविधि एम्बेड करना (स्प्लिट कॉन्फ़िगरेशन देखें सेक्शन में बताया गया है). इसके बाद, OEM के हिसाब से बनाए गए डिवाइस यह तय कर सकते हैं कि फ़िक्स्ड-पोर्ट्रेट गतिविधियों को लेटरबॉक्स में दिखाना है या नहीं.

स्प्लिट कॉन्फ़िगरेशन

बांटने के नियम, गतिविधि के बंटवारे को कॉन्फ़िगर करते हैं. स्प्लिट नियमों को एक्सएमएल कॉन्फ़िगरेशन फ़ाइल में या Jetpack WindowManager एपीआई कॉल करके तय किया जाता है.

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

ये काम करें:

  1. अपने ऐप्लिकेशन के मॉड्यूल-लेवल पर, WindowManager लाइब्रेरी की नई डिपेंडेंसी जोड़ें build.gradle फ़ाइल का उदाहरण:

    implementation 'androidx.window:window:1.1.0-beta02'

    WindowManager लाइब्रेरी, गतिविधि को एम्बेड करने के लिए ज़रूरी सभी कॉम्पोनेंट उपलब्ध कराती है.

  2. सिस्टम को बताएं कि आपके ऐप्लिकेशन में गतिविधि को एम्बेड करने की सुविधा लागू की गई है.

    ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल के <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 और इसके बाद के वर्शन वाले रिलीज़ पर, गतिविधि एम्बेड करने वाले स्प्लिट बंद रहते हैं. ऐसा तब तक होता है, जब तक प्रॉपर्टी को मेनिफ़ेस्ट में जोड़कर, 'सही है' पर सेट नहीं किया जाता.

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

एक्सएमएल कॉन्फ़िगरेशन

गतिविधि को एम्बेड करने के लिए, एक्सएमएल पर आधारित लागू करने का तरीका बनाने के लिए, यह तरीका अपनाएं:

  1. ऐसी एक्सएमएल रिसॉर्स फ़ाइल बनाएं जो ये काम करती हो:

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

    उदाहरण के लिए:

    <!-- 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>
    
  2. कोई इनिशलाइज़र बनाएं.

    WindowManager RuleController कॉम्पोनेंट, एक्सएमएल कॉन्फ़िगरेशन फ़ाइल को पार्स करता है और सिस्टम के लिए नियम उपलब्ध कराता है. जेटपैक Startup लाइब्रेरी Initializer, एक्सएमएल फ़ाइल को ऐप्लिकेशन स्टार्टअप पर RuleController, ताकि नियम तब लागू हों, जब कोई गतिविधियां शुरू हो जाती हैं.

    कोई इनिशलाइज़र बनाने के लिए, यह तरीका अपनाएं:

    1. अपने मॉड्यूल-लेवल की build.gradle फ़ाइल में, Jetpack Startup लाइब्रेरी की सबसे नई डिपेंडेंसी जोड़ें. उदाहरण के लिए:

      implementation 'androidx.startup:startup-runtime:1.1.1'

    2. ऐसी क्लास बनाएं जो 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();
           }
      }
  3. नियमों की परिभाषाओं के लिए, कॉन्टेंट देने वाला कोई ऐप्लिकेशन बनाएं.

    अपनी ऐप्लिकेशन मेनिफ़ेस्ट फ़ाइल में, <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

कुछ एपीआई की मदद से, प्रोग्राम के हिसाब से गतिविधि एम्बेड करने की प्रोसेस लागू की जा सकती है कॉल. इसकी सब-क्लास की onCreate() विधि में कॉल करें Application, ताकि यह पक्का किया जा सके कि किसी भी गतिविधि से पहले नियम लागू हैं लॉन्च.

प्रोग्राम के हिसाब से अपने-आप होने वाली गतिविधियों का बंटवारा बनाने के लिए, ये काम करें:

  1. बांटने का नियम बनाएं:

    1. 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
      );
    2. किसी फ़िल्टर सेट में फ़िल्टर जोड़ना:

      Kotlin

      val filterSet = setOf(splitPairFilter)

      Java

      Set<SplitPairFilter> filterSet = new HashSet<>();
      filterSet.add(splitPairFilter);
    3. स्प्लिट के लिए लेआउट एट्रिब्यूट बनाएं:

      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(): इससे पता चलता है कि गतिविधि कंटेनर कैसे काम करते हैं एक-दूसरे के सापेक्ष बनाए जाते हैं, पहले प्राथमिक कंटेनर.
    4. 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(): डिसप्ले की सबसे कम चौड़ाई को सेट करता है (इंच डेंसिटी-इंडिपेंडेंट पिक्सल, dp) जो स्प्लिट को चालू करते हैं.
      • setMinSmallestWidthDp(): डिवाइस के ओरिएंटेशन के बावजूद, स्प्लिट मोड चालू करने के लिए, दो डिसप्ले डाइमेंशन में से छोटे डाइमेंशन की कम से कम वैल्यू (dp में) सेट करता है.
      • setMaxAspectRatioInPortrait(): यह विकल्प, सबसे ज़्यादा आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) सेट करता है किस गतिविधि के लिए पोर्ट्रेट ओरिएंटेशन में अनुपात (height:width) स्प्लिट दिख रहे हैं. अगर पोर्ट्रेट डिसप्ले का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) तय सीमा से ज़्यादा हो गया है, तो स्प्लिट इन पर ध्यान दिए बिना बंद हो जाते हैं डिसप्ले की चौड़ाई. ध्यान दें: डिफ़ॉल्ट वैल्यू 1.4 है, जो इसके नतीजे, पोर्ट्रेट मोड में पूरी टास्क विंडो में मौजूद गतिविधियों के बारे में हैं का उपयोग करने के लिए डिज़ाइन किया गया है. SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT और setMaxAspectRatioInLandscape() लेख भी पढ़ें. लैंडस्केप ALWAYS_ALLOW है.
      • setFinishPrimaryWithSecondary(): यह सेट करता है कि सभी कैंपेन को किस तरह पूरा किया जाए सेकंडरी कंटेनर में होने वाली गतिविधियां, प्राइमरी कंटेनर है. NEVER बताता है कि सिस्टम को प्रोसेस पूरी नहीं करनी चाहिए जब सेकंडरी क्लास में सभी गतिविधियां हों, तो मुख्य गतिविधियाँ कंटेनर फ़िनिश (गतिविधियां खत्म करना देखें).
      • setFinishSecondaryWithPrimary(): इससे यह सेट होता है कि मुख्य कंटेनर में सभी गतिविधियां पूरी होने पर, सेकंडरी कंटेनर में मौजूद गतिविधियों पर क्या असर पड़ता है. ALWAYS बताता है कि सिस्टम को हमेशा सभी गतिविधियों को सेकंडरी कंटेनर में पूरा करें प्राथमिक कंटेनर में समाप्त होता है (देखें गतिविधियां खत्म करना).
      • setClearTop(): इससे पता चलता है कि कंटेनर में नई गतिविधि शुरू होने पर, सेकंडरी कंटेनर में सभी गतिविधियां पूरी हो गई हैं या नहीं. false वैल्यू से पता चलता है कि नई गतिविधियां इन्हें सेकंडरी कंटेनर में पहले से मौजूद गतिविधियों के ऊपर रखा जाता है.
    5. WindowManager RuleController का सिंगलटन इंस्टेंस पाएं और नियम जोड़ें:

      Kotlin

        val ruleController = RuleController.getInstance(this)
        ruleController.addRule(splitPairRule)
        

      Java

        RuleController ruleController = RuleController.getInstance(this);
        ruleController.addRule(splitPairRule);
        
  2. सेकंडरी कंटेनर के लिए तब कोई प्लेसहोल्डर बनाएं, जब सामग्री उपलब्ध नहीं है:

    1. एक ActivityFilter बनाएं, जिससे उस गतिविधि की पहचान हो सके जिससे प्लेसहोल्डर टास्क विंडो को अलग-अलग करके शेयर करता है:

      Kotlin

      val placeholderActivityFilter = ActivityFilter(
          ComponentName(this, ListActivity::class.java),
          null
      )

      Java

      ActivityFilter placeholderActivityFilter = new ActivityFilter(
          new ComponentName(this, ListActivity.class),
          null
      );
    2. किसी फ़िल्टर सेट में फ़िल्टर जोड़ना:

      Kotlin

      val placeholderActivityFilterSet = setOf(placeholderActivityFilter)

      Java

      Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>();
      placeholderActivityFilterSet.add(placeholderActivityFilter);
    3. किसी प्रॉडक्ट की पिच के लिए 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(): दो डिसप्ले में से सबसे छोटी सबसे छोटी वैल्यू (डीपी) सेट करता है डाइमेंशन को स्प्लिट की अनुमति देनी चाहिए, भले ही कोई भी डिवाइस स्क्रीन की दिशा.
      • setMaxAspectRatioInPortrait(): पोर्ट्रेट ओरिएंटेशन में, डिसप्ले के लिए आसपेक्ट रेशियो (ऊंचाई:चौड़ाई) की ज़्यादा से ज़्यादा वैल्यू सेट करता है. यह वैल्यू, गतिविधि के बंटवारे के लिए डिसप्ले की जाती है. ध्यान दें: डिफ़ॉल्ट वैल्यू 1.4 होती है. इसकी वजह से, ज़्यादातर टैबलेट पर टास्क विंडो में पोर्ट्रेट ओरिएंटेशन में गतिविधियां भर जाती हैं. इन्हें भी देखें SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT और setMaxAspectRatioInLandscape(). लैंडस्केप के लिए डिफ़ॉल्ट वैल्यू ALWAYS_ALLOW है.
      • setFinishPrimaryWithPlaceholder(): सेट करता है कि प्लेसहोल्डर गतिविधि को पूरा करने से गतिविधियों पर क्या असर पड़ता है प्राथमिक कंटेनर में शामिल करें. 'हमेशा' यह बताता है कि सिस्टम को प्लेसहोल्डर होने पर, प्राइमरी कंटेनर में सभी गतिविधियों को पूरा किया जा सकता है फ़िनिश (गतिविधियां खत्म करना देखें).
      • setSticky(): यह तय करता है कि प्लेसहोल्डर ऐक्टिविटी, छोटे डिसप्ले पर ऐक्टिविटी स्टैक में सबसे ऊपर दिखेगी या नहीं. ऐसा तब होता है, जब प्लेसहोल्डर पहली बार कम से कम तय चौड़ाई वाले स्प्लिट में दिखता है.
    4. WindowManager RuleController में नियम जोड़ें:

      Kotlin

      ruleController.addRule(splitPlaceholderRule)

      Java

      ruleController.addRule(splitPlaceholderRule);
  3. उन गतिविधियों के बारे में बताएं जिन्हें कभी भी बंटवारे का हिस्सा नहीं होना चाहिए:

    1. ऐसा ActivityFilter बनाएं जो किसी ऐसी ऐक्टिविटी की पहचान करता हो जिसे हमेशा टास्क के डिसप्ले एरिया में दिखाया जाना चाहिए:

      Kotlin

      val expandedActivityFilter = ActivityFilter(
        ComponentName(this, ExpandedActivity::class.java),
        null
      )

      Java

      ActivityFilter expandedActivityFilter = new ActivityFilter(
        new ComponentName(this, ExpandedActivity.class),
        null
      );
    2. किसी फ़िल्टर सेट में फ़िल्टर जोड़ना:

      Kotlin

      val expandedActivityFilterSet = setOf(expandedActivityFilter)

      Java

      Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>();
      expandedActivityFilterSet.add(expandedActivityFilter);
    3. ActivityRule बनाएं:

      Kotlin

      val activityRule = ActivityRule.Builder(expandedActivityFilterSet)
          .setAlwaysExpand(true)
          .build()

      Java

      ActivityRule activityRule = new ActivityRule.Builder(
          expandedActivityFilterSet
      ).setAlwaysExpand(true)
       .build();

      ActivityRule.Builder नियम बनाता और कॉन्फ़िगर करता है:

      • expandedActivityFilterSet: इसमें गतिविधि फ़िल्टर होते हैं, जो उन गतिविधियों की पहचान करके यह तय करते हैं कि नियम कब लागू किया जाए जिन्हें आपको स्प्लिट से बाहर रखना है.
      • setAlwaysExpand(): इससे पता चलता है कि गतिविधि की जानकारी भरनी चाहिए या नहीं टास्क विंडो पर क्लिक करें.
    4. WindowManager RuleController में नियम जोड़ें:

      Kotlin

      ruleController.addRule(activityRule)

      Java

      ruleController.addRule(activityRule);

क्रॉस-ऐप्लिकेशन एम्बेड करना

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

उदाहरण के लिए, सेटिंग ऐप्लिकेशन वॉलपेपर सिलेक्टर की गतिविधि को एम्बेड कर सकता है वॉलपेपर पिकर ऐप:

14वीं इमेज. सेटिंग ऐप्लिकेशन (बाईं ओर मेन्यू), जिसमें वॉलपेपर चुनने वाला टूल, एम्बेड की गई गतिविधि (दाईं ओर) के तौर पर दिख रहा है.

ट्रस्ट मॉडल

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

क्रॉस-ऐप्लिकेशन गतिविधि को एम्बेड करने के गलत इस्तेमाल को रोकने के लिए, Android ऐप्लिकेशन को अपनी गतिविधियों को एम्बेड करने की अनुमति देने के लिए ऑप्ट-इन करना होगा. ऐप्लिकेशन, होस्ट को भरोसेमंद या गैर-भरोसेमंद के तौर पर मार्क कर सकते हैं.

भरोसेमंद होस्ट

अन्य ऐप्लिकेशन को प्रस्तुत किए जाने और पूरी तरह से नियंत्रित करने की अनुमति देने के लिए गतिविधियों के लिए, होस्ट का SHA-256 सर्टिफ़िकेट तय करें ऐप्लिकेशन की android:knownActivityEmbeddingCerts विशेषता में आपके ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल के <activity> या <application> एलिमेंट.

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>

ऐप्लिकेशन के मालिक, GradlesigningReport टास्क को चलाकर 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 कॉल का इस्तेमाल करके, रनटाइम के दौरान तय किया जाता है.

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

अगर एम्बेड की गई कोई गतिविधि, उसी टास्क में नई गतिविधि शुरू करती है और नई गतिविधि ने क्रॉस-ऐप्लिकेशन एम्बेड करने के लिए ऑप्ट-इन नहीं किया है, तो गतिविधि, एम्बेड किए गए कंटेनर में गतिविधि को ओवरले करने के बजाय, पूरे टास्क के बाउंड पर कब्जा कर लेती है.

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

स्प्लिट के उदाहरण

फ़ुल विंडो से स्प्लिट करें

15वीं इमेज. गतिविधि A, गतिविधि B को एक तरफ़ शुरू करती है.

किसी भी रीफ़ैक्टरिंग की ज़रूरत नहीं है. स्प्लिट के लिए कॉन्फ़िगरेशन को स्टैटिक तौर पर या रनटाइम पर तय किया जा सकता है. इसके बाद, किसी भी अतिरिक्त पैरामीटर के बिना Context#startActivity() को कॉल किया जा सकता है.

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

डिफ़ॉल्ट रूप से बांटें

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

16वीं इमेज. एक साथ दो गतिविधियां खोलकर बनाया गया स्प्लिट. एक गतिविधि प्लेसहोल्डर है.

प्लेसहोल्डर के साथ स्प्लिट बनाने के लिए, प्लेसहोल्डर बनाएं और उसे मुख्य गतिविधि से असोसिएट करें:

<SplitPlaceholderRule
    window:placeholderActivityName=".PlaceholderActivity">
    <ActivityFilter
        window:activityName=".MainActivity"/>
</SplitPlaceholderRule>

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

17वीं इमेज. डीप लिंक की ज़्यादा जानकारी वाली ऐक्टिविटी, छोटी स्क्रीन पर अकेले दिखाई गई है, लेकिन बड़ी स्क्रीन पर सूची वाली ऐक्टिविटी के साथ दिखाई गई है.

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

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>

कॉन्फ़िगरेशन एट्रिब्यूट सेक्शन देखें.

अलग-अलग कंटेनर में कई गतिविधियां

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

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

Kotlin

class DetailActivity {
    . . .
    fun onOpenSubDetail() {
      startActivity(Intent(this, SubDetailActivity::class.java))
    }
}

Java

public class DetailActivity {
    . . .
    void onOpenSubDetail() {
        startActivity(new Intent(this, SubDetailActivity.class));
    }
}

ज़्यादा जानकारी वाली गतिविधि को ज़्यादा जानकारी वाली गतिविधि के ऊपर रखा जाता है, जिससे वह छिप जाती है:

इसके बाद, उपयोगकर्ता स्टैक पर वापस नेविगेट करके, जानकारी के पिछले लेवल पर वापस जा सकता है:

19वां डायग्राम. गतिविधि को स्टैक के सबसे ऊपरी हिस्से से हटाया गया.

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

नए टास्क में की जाने वाली गतिविधियां

जब स्प्लिट टास्क विंडो में मौजूद गतिविधियां, किसी नए टास्क में गतिविधियां शुरू करती हैं, तो नया टास्क उस टास्क से अलग होता है जिसमें स्प्लिट शामिल होता है और उसे पूरी विंडो में दिखाया जाता है. 'हाल ही के' स्क्रीन पर दो टास्क दिखते हैं: स्प्लिट में किया गया टास्क और नया टास्क टास्क.

इमेज 20. गतिविधि B से नए टास्क में गतिविधि C शुरू करें.

गतिविधि बदलना

गतिविधियों को सेकंडरी कंटेनर स्टैक में बदला जा सकता है; उदाहरण के लिए, जब मुख्य गतिविधि का इस्तेमाल, टॉप-लेवल नेविगेशन और दूसरी गतिविधि के लिए किया जाता है एक चयनित गंतव्य है. टॉप-लेवल नेविगेशन से चुने गए हर विकल्प से, सेकंडरी कंटेनर में एक नई गतिविधि शुरू होनी चाहिए. साथ ही, पहले से मौजूद गतिविधि या गतिविधियों को हटाना चाहिए.

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

अगर ऐप्लिकेशन, सेकंडरी कंटेनर में की गई गतिविधि को पूरा नहीं करता है, तो नेविगेशन के लिए चुने गए विकल्प में बदलाव किया जा सकता है. छोटा किया जाता है (जब डिवाइस फ़ोल्ड हो). उदाहरण के लिए, अगर आपके पास मुख्य पैनल में एक मेन्यू है और स्क्रीन 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)));
    }
}

इसके अलावा, एक ही सेकंडरी गतिविधि का इस्तेमाल करें और प्राइमरी (मेन्यू) गतिविधि से नए इंटेंट भेजें. ये इंटेंट उसी इंस्टेंस को रिज़ॉल्व करते हैं, लेकिन सेकंडरी कंटेनर में स्टेटस या यूज़र इंटरफ़ेस (यूआई) अपडेट को ट्रिगर करते हैं.

एक से ज़्यादा स्प्लिट

ऐप्लिकेशन, साइड में अन्य गतिविधियां लॉन्च करके, कई लेवल का डीप नेविगेशन उपलब्ध करा सकते हैं.

जब किसी सेकंडरी कंटेनर में कोई गतिविधि, किसी नई गतिविधि को साइड में लॉन्च करती है, तो नया स्प्लिट मौजूदा स्प्लिट के ऊपर बनाया जाता है.

इमेज 22. गतिविधि B, गतिविधि C को एक तरफ़ शुरू करती है.

पिछली गतिविधियों में, पहले खोली गई सभी गतिविधियां शामिल होती हैं. इससे उपयोगकर्ता इन कामों को कर सकते हैं C पूरा करने के बाद, A/B स्प्लिट पर जाएं.

स्टैक में गतिविधियां A, B, और C. ये गतिविधियां
          ऊपर से नीचे के क्रम में: C, B, A.

नया स्प्लिट बनाने के लिए, मौजूदा सेकंडरी कंटेनर के बगल में नई गतिविधि लॉन्च करें. 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));
    }
}

अलग-अलग स्थितियों में बदलाव पर प्रतिक्रिया दें

किसी ऐप्लिकेशन की अलग-अलग गतिविधियों में ऐसे यूज़र इंटरफ़ेस (यूआई) एलिमेंट हो सकते हैं जो एक जैसा परफ़ॉर्म करते हों फ़ंक्शन; उदाहरण के लिए, ऐसा कंट्रोल जो खाते वाली विंडो को खोलता है सेटिंग.

23वीं इमेज. अलग-अलग गतिविधियां, जिनमें फ़ंक्शन के हिसाब से एक जैसे यूज़र इंटरफ़ेस (यूआई) एलिमेंट हों.

अगर दो गतिविधियों में एक ही यूज़र इंटरफ़ेस (यूआई) एलिमेंट है और वे स्प्लिट में हैं, तो दोनों गतिविधियों में एलिमेंट दिखाना ग़ैर-ज़रूरी है. साथ ही, इससे शायद भ्रम भी हो सकता है.

24 इमेज. गतिविधि के बंटवारे में डुप्लीकेट यूज़र इंटरफ़ेस (यूआई) एलिमेंट.

यह जानने के लिए कि गतिविधियां कब अलग-अलग होती हैं, 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>

गतिविधियां पूरी करना

उपयोगकर्ता, स्प्लिट स्क्रीन के दोनों हिस्सों पर मौजूद गतिविधियों को पूरा कर सकते हैं. इसके लिए, उन्हें डिसप्ले के किनारे से स्वाइप करना होगा:

25वां डायग्राम. स्वाइप जेस्चर से गतिविधि B को खत्म करना.
इमेज 26. स्वाइप करने के जेस्चर का इस्तेमाल करने से जुड़ी गतिविधि A.

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

कंटेनर में सभी गतिविधियों को पूरा करने का असर कंटेनर, स्प्लिट कॉन्फ़िगरेशन पर निर्भर करता है.

कॉन्फ़िगरेशन एट्रिब्यूट

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

  • window:finishPrimaryWithSecondary — सभी ऐक्टिविटी को किस तरह पूरा किया गया सेकंडरी कंटेनर, मुख्य कंटेनर की गतिविधियों पर असर डालता है
  • window:finishSecondaryWithPrimary — प्राइमरी कंटेनर में सभी गतिविधियों को पूरा करने से, सेकंडरी कंटेनर में मौजूद गतिविधियों पर क्या असर पड़ता है

एट्रिब्यूट की संभावित वैल्यू में ये शामिल हैं:

  • always — हमेशा उसी कंटेनर में गतिविधियां पूरी करें जिससे वे जुड़ी हैं
  • never — उससे जुड़े कंटेनर में गतिविधियां कभी न खत्म करें
  • adjacent — इससे जुड़े कंटेनर में की गई गतिविधियों को तब पूरा करें, जब दो कंटेनर एक-दूसरे के बगल में दिखाए जाते हैं, न कि जब जब दो कंटेनर स्टैक किए गए हों

उदाहरण के लिए:

<SplitPairRule
    &lt;!-- Do not finish primary container activities when all secondary container activities finish. --&gt;
    window:finishPrimaryWithSecondary="never"
    &lt;!-- Finish secondary container activities when all primary container activities finish. --&gt;
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

डिफ़ॉल्ट कॉन्फ़िगरेशन

जब स्प्लिट स्क्रीन के किसी कंटेनर में मौजूद सभी गतिविधियां पूरी हो जाती हैं, तो बाकी कंटेनर पूरी विंडो पर दिखने लगता है:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

गतिविधियों A और B वाला स्प्लिट. A की प्रोसेस पूरी हो गई है, इसलिए B को पूरी विंडो में दिखाया जा रहा है.

गतिविधियों A और B वाला स्प्लिट. B ख़त्म हो गया, A को छोड़ दिया
          पूरी विंडो को घेर लेते हैं.

साथ मिलकर गतिविधियां पूरी करना

सभी गतिविधियों के होने पर, मुख्य कंटेनर में गतिविधियों को अपने-आप पूरा होने दें सेकंडरी कंटेनर फ़िनिश में:

<SplitPairRule
    window:finishPrimaryWithSecondary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

गतिविधियों A और B को शामिल करें. B खत्म हो गया है, जो
          टास्क विंडो को खाली छोड़कर, A पूरा करता है.

गतिविधियों A और B को शामिल करें. A ने अपना टास्क पूरा कर लिया है, इसलिए वह टास्क विंडो से बाहर निकल गया है.

प्राइमरी कंटेनर में सभी गतिविधियां पूरी होने पर, सेकंडरी कंटेनर में गतिविधियां अपने-आप पूरी हो जाएं:

<SplitPairRule
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

गतिविधियों A और B को शामिल करें. A खत्म हो गया है, जो यह भी
          टास्क विंडो को खाली छोड़कर, B पूरा हो जाता है.

गतिविधियों A और B को शामिल करें. B खत्म हो गया है, A को अकेला छोड़ रहे हैं
          पर क्लिक करें.

जब सभी गतिविधियां एक साथ पूरी करें, तो मुख्य या सेकंडरी कंटेनर फ़िनिश:

<SplitPairRule
    window:finishPrimaryWithSecondary="always"
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

गतिविधियों A और B को शामिल करें. A पूरा हो गया है, जिससे B भी पूरा हो गया है. इससे टास्क विंडो खाली हो जाती है.

गतिविधियों A और B को शामिल करें. B पूरा हो गया है, जिससे A भी पूरा हो गया है. इससे टास्क विंडो खाली हो जाती है.

कंटेनर में कई गतिविधियां पूरी करना

अगर स्प्लिट कंटेनर में कई गतिविधियां स्टैक की गई हैं, तो स्टैक में सबसे नीचे मौजूद गतिविधि को पूरा करने पर, सबसे ऊपर मौजूद गतिविधियां अपने-आप पूरी नहीं होतीं.

उदाहरण के लिए, अगर सेकंडरी कंटेनर में दो गतिविधियां हैं, तो B के ऊपर C:

ऐक्टिविटी C वाला सेकंडरी ऐक्टिविटी स्टैक, ऐक्टिविटी B के ऊपर स्टैक किया गया है
          और यह ऐक्टिविटी A वाले प्राइमरी ऐक्टिविटी स्टैक के ऊपर स्टैक किया गया है.

और स्प्लिट का कॉन्फ़िगरेशन गतिविधियों के कॉन्फ़िगरेशन से तय होता है A और B:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

टॉप गतिविधि को खत्म करने से स्प्लिट बरकरार रहता है.

प्राइमरी कंटेनर में गतिविधि A और सेकंडरी में गतिविधियां B और C, C को B के ऊपर स्टैक किया गया. C खत्म होता है, A और B को छोड़ दिया जाता है
          गतिविधि का बंटवारा.

सेकंडरी कंटेनर की सबसे नीचे (रूट) मौजूद ऐक्टिविटी को पूरा करने पर, उसके ऊपर मौजूद ऐक्टिविटी नहीं हटतीं. इसलिए, स्प्लिट भी बना रहता है.

प्राइमरी कंटेनर में गतिविधि A और गतिविधि B और C के साथ बांटें
          सेकंडरी, B के ऊपर C रखा गया. B ख़त्म हो गया और A और C को छोड़ दिया
          गतिविधि का बंटवारा.

गतिविधियों को एक साथ खत्म करने के लिए, कोई भी अन्य नियम भी लागू किया जाता है. जैसे, मुख्य गतिविधि के साथ सेकंडरी गतिविधि को खत्म करना:

<SplitPairRule
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

प्राइमरी कंटेनर में गतिविधि A और सेकंडरी कंटेनर में गतिविधियां B और C, जिसमें C, B के ऊपर स्टैक की गई है. एक फ़िनिश, यह भी
          B और C के आखिरी चरण पूरे कर लिए.

अगर स्प्लिट को प्राइमरी और सेकंडरी, दोनों को एक साथ खत्म करने के लिए कॉन्फ़िगर किया गया है, तो:

<SplitPairRule
    window:finishPrimaryWithSecondary="always"
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

प्राइमरी कंटेनर में गतिविधि A और सेकंडरी में गतिविधियां B और C, C को B के ऊपर स्टैक किया गया. C खत्म होता है, A और B को छोड़ दिया जाता है
          गतिविधि का बंटवारा.

प्राइमरी कंटेनर में गतिविधि A और सेकंडरी में गतिविधियां B और C, C को B के ऊपर स्टैक किया गया. B ख़त्म हो गया और A और C को छोड़ दिया
          गतिविधि का बंटवारा.

प्राइमरी कंटेनर में गतिविधि A और सेकंडरी में गतिविधियां B और C, C को B के ऊपर स्टैक किया गया. एक फ़िनिश, B भी फ़िनिशिंग और
          सी॰

रनटाइम के दौरान स्प्लिट प्रॉपर्टी बदलना

किसी सक्रिय और दृश्यमान स्प्लिट की प्रॉपर्टी बदली नहीं जा सकती हैं. स्प्लिट के नियमों में बदलाव करने से, अन्य ऐक्टिविटी लॉन्च और नए कंटेनर पर असर पड़ता है. हालांकि, मौजूदा और चालू स्प्लिट पर असर नहीं पड़ता.

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

डाइनैमिक स्प्लिट प्रॉपर्टी

Android 15 (एपीआई लेवल 35) और इसके बाद के वर्शन पर, Jetpack WindowManager 1.4 और इसके बाद के वर्शन की डाइनैमिक सुविधाएं काम करती हैं. इनकी मदद से, गतिविधि को एम्बेड करने वाले स्प्लिट को कॉन्फ़िगर किया जा सकता है. इनमें ये सुविधाएं शामिल हैं:

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

पैनल को बड़ा करना

पैनल को बड़ा करने की सुविधा की मदद से, उपयोगकर्ता दो पैनल वाले लेआउट में, दोनों गतिविधियों के लिए स्क्रीन पर तय किए गए स्पेस में बदलाव कर सकते हैं.

विंडो डिवाइडर के लुक को पसंद के मुताबिक बनाने और डिवाइडर सेट करने के लिए खींचने और छोड़ने लायक रेंज में बदलाव करने के लिए, ये काम करें:

  1. DividerAttributes का इंस्टेंस बनाना

  2. डिवाइडर एट्रिब्यूट को पसंद के मुताबिक बनाएं:

    • 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();

गतिविधि पिन करना

गतिविधि पिन करने से उपयोगकर्ता, स्प्लिट विंडो में से किसी एक विंडो को पिन कर सकते हैं, ताकि जब तक उपयोगकर्ता अन्य विंडो में नेविगेट करते हैं, तब तक गतिविधि बनी रहती है. Gemini पर आपकी गतिविधि पिन करने से मल्टीटास्किंग (एक साथ कई काम करने) का बेहतर अनुभव मिलता है.

अपने ऐप्लिकेशन में गतिविधि को पिन करने की सुविधा चालू करने के लिए, यह तरीका अपनाएं:

  1. जिस गतिविधि को पिन करना है उसकी लेआउट फ़ाइल में बटन जोड़ें. उदाहरण के लिए, सूची‑जानकारी वाले लेआउट की गतिविधि की जानकारी:

    <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>
    
  2. गतिविधि की onCreate() विधि में, इस पर एक ऑनक्लिक श्रोता सेट करें बटन:

    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) या इसके बाद के वर्शन पर चलने वाले ज़्यादातर बड़े स्क्रीन वाले डिवाइसों में यह इंटरफ़ेस शामिल होता है. हालांकि, कुछ बड़े स्क्रीन वाले डिवाइसों में विंडो एक्सटेंशन इंटरफ़ेस नहीं होता. ऐसा इसलिए होता है, क्योंकि ये डिवाइस एक से ज़्यादा गतिविधियां नहीं चला सकते. अगर बड़ी स्क्रीन वाले डिवाइस पर मल्टी-विंडो काम नहीं करता मोड में है, तो हो सकता है कि उसमें गतिविधि एम्बेड करने की सुविधा काम न करे.

अन्य संसाधन