कॉन्फ़िगरेशन के बदलावों को हैंडल करना

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

  • ऐप्लिकेशन का डिसप्ले साइज़
  • स्क्रीन की दिशा
  • फ़ॉन्ट का साइज़ और मोटाई
  • स्थान-भाषा
  • गहरे रंग वाले मोड बनाम हल्के रंग वाला मोड
  • कीबोर्ड की उपलब्धता

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

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

ऐक्टिविटी को फिर से बनाना

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

आम तौर पर, Activity कंपोज़ेबल के लिए होस्ट के तौर पर काम करता है. Activity को फिर से बनाने पर, Compose भी नई कॉन्फ़िगरेशन वैल्यू का इस्तेमाल करके आपके यूज़र इंटरफ़ेस (यूआई) को फिर से बनाता है.

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

मनोरंजन का उदाहरण

मान लें कि एक कंपोज़ेबल है, जो स्ट्रिंग रिसॉर्स का इस्तेमाल करके स्टैटिक टाइटल दिखाता है:

// In the res/values/strings.xml file
// <string name="compose">Jetpack Compose</string>

// In your Compose code
Text(
    text = stringResource(R.string.compose)
)

Activity बनाने पर, Text कंपोज़ेबल, मौजूदा कॉन्फ़िगरेशन (जैसे कि भाषा) को पढ़ता है और सही स्ट्रिंग रिसॉर्स को हल करता है.

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

रीक्रिएशन से, Activity में फ़ील्ड के तौर पर सेव की गई किसी भी स्थिति को भी मिटा दिया जाता है.

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

Compose में स्थिति सेव करने के बारे में ज़्यादा जानने के लिए, Compose में यूज़र इंटरफ़ेस (यूआई) की स्थिति सेव करना लेख पढ़ें.

उपयोगकर्ताओं की उम्मीदें

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

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

  • डिवाइस को घुमाना
  • मल्टी-विंडो मोड में जाना
  • मल्टी-विंडो मोड या फ़्री-फ़ॉर्म विंडो में ऐप्लिकेशन का साइज़ बदलना
  • एक से ज़्यादा डिसप्ले वाले फ़ोल्डेबल डिवाइस को फ़ोल्ड करना
  • सिस्टम की थीम बदलना, जैसे कि गहरे रंग वाला मोड बनाम हल्के रंग वाला मोड
  • फ़ॉन्ट का साइज़ बदलना
  • सिस्टम या ऐप्लिकेशन की भाषा बदलना
  • हार्डवेयर कीबोर्ड को कनेक्ट या डिसकनेक्ट करना
  • डॉक को कनेक्ट या डिसकनेक्ट करना

Activity फिर से बनाने के दौरान, काम की स्थिति को बनाए रखने के लिए कई तरीके अपनाए जा सकते हैं. इनमें से किसका इस्तेमाल करना है, यह इस बात पर निर्भर करता है कि आपको किस तरह की स्थिति बनाए रखनी है:

  • जटिल या बड़े डेटा के लिए, प्रोसेस बंद होने की समस्या को ठीक करने के लिए लोकल परसिस्टेंस का इस्तेमाल किया जाता है. स्थायी लोकल स्टोरेज में डेटाबेस या DataStore शामिल होते हैं.
  • बनाए रखे गए ऑब्जेक्ट, जैसे कि ViewModel इंस्टेंस. इनका इस्तेमाल, उपयोगकर्ता के ऐप्लिकेशन का इस्तेमाल करते समय, मेमोरी में यूज़र इंटरफ़ेस (यूआई) से जुड़ी स्थिति को मैनेज करने के लिए किया जाता है.
  • rememberSaveable का इस्तेमाल करके, कॉन्फ़िगरेशन में होने वाले बदलावों और सिस्टम की वजह से प्रोसेस बंद होने पर, यूज़र इंटरफ़ेस (यूआई) की स्थिति को बनाए रखें. यह उस स्थिति के लिए सही है जो उपयोगकर्ता के इनपुट, स्क्रोल करने की जगह या नेविगेशन पर निर्भर करती है, लेकिन ViewModel में नहीं आती है.

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

गतिविधि के हिसाब से मनोरंजन को सीमित करना

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

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

Compose में सीधे तौर पर कॉन्फ़िगरेशन में हुए बदलावों को हैंडल करने के कई फ़ायदे हैं:

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

कॉन्फ़िगरेशन में हुए कुछ बदलावों के लिए, गतिविधि को फिर से बनाने की सुविधा बंद करने के लिए, AndroidManifest.xml फ़ाइल में <activity> एंट्री में android:configChanges में कॉन्फ़िगरेशन टाइप जोड़ें. संभावित वैल्यू, android:configChanges एट्रिब्यूट के दस्तावेज़ में दिखती हैं.

यहां दिया गया मेनिफ़ेस्ट कोड, स्क्रीन ओरिएंटेशन और कीबोर्ड की उपलब्धता में बदलाव होने पर, MyActivity के लिए Activity को फिर से बनाने की सुविधा बंद कर देता है:

<activity
    android:name=".MyActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
    android:label="@string/app_name">

Android 17

Android 17 (एपीआई लेवल 37) से, सिस्टम अब डिफ़ॉल्ट रूप से कई कॉन्फ़िगरेशन में बदलाव करने के लिए, गतिविधियों को रीस्टार्ट नहीं करता. आम तौर पर, इन बदलावों के लिए पूरे यूज़र इंटरफ़ेस (यूआई) को फिर से बनाने की ज़रूरत नहीं होती. इसके बजाय, गतिविधियां चालू रहती हैं और उन्हें onConfigurationChanged() कॉलबैक के ज़रिए अपडेट मिलते हैं. कॉन्फ़िगरेशन में किए गए बदलावों में ये शामिल हैं:

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

<activity
    android:name=".MyActivity"
    android:recreateOnConfigChanges="keyboard|keyboardHidden|navigation|colorMode|touchscreen|...">
    ...
</activity>

कॉन्फ़िगरेशन में हुए बदलावों पर प्रतिक्रिया देना

Jetpack Compose की मदद से, आपका ऐप्लिकेशन कॉन्फ़िगरेशन में हुए बदलावों पर ज़्यादा आसानी से प्रतिक्रिया दे सकता है. हालांकि, अगर कॉन्फ़िगरेशन में किए गए सभी बदलावों के लिए Activity को बंद कर दिया जाता है, तो आपका ऐप्लिकेशन अब भी कॉन्फ़िगरेशन में किए गए बदलावों को सही तरीके से हैंडल करेगा.

Configuration ऑब्जेक्ट, Compose UI के हेरारकी में LocalConfiguration कंपोज़िशन लोकल के साथ उपलब्ध है. जब भी इसमें बदलाव होता है, तब LocalConfiguration.current से डेटा पढ़ने वाले कंपोज़ेबल फ़ंक्शन फिर से कंपोज़ होते हैं. CompositionLocal के काम करने के तरीके के बारे में जानने के लिए, CompositionLocal के साथ स्थानीय स्कोप वाला डेटा लेख पढ़ें.

उदाहरण

यहां दिए गए उदाहरण में, कंपोज़ेबल एक खास फ़ॉर्मैट में तारीख दिखाता है. सिस्टम की स्थान-भाषा के कॉन्फ़िगरेशन में बदलाव होने पर, कंपोज़ेबल LocalConfiguration.current के साथ ConfigurationCompat.getLocales को कॉल करके प्रतिक्रिया देता है.

@Composable
fun DateText(year: Int, dayOfYear: Int) {
    val dateTimeFormatter = DateTimeFormatter.ofPattern(
        "MMM dd",
        ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
    )
    Text(
        dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
    )
}

जब स्थान-भाषा बदलती है, तब Activity को फिर से बनाने से बचने के लिए, Activity को होस्ट करने वाले Compose कोड को स्थान-भाषा के कॉन्फ़िगरेशन में होने वाले बदलावों से ऑप्ट आउट करना होगा. इसके लिए, android:configChanges को locale|layoutDirection पर सेट करें.

कॉन्फ़िगरेशन में बदलाव: मुख्य कॉन्सेप्ट और सबसे सही तरीके

कॉन्फ़िगरेशन में बदलाव करते समय, आपको इन मुख्य बातों के बारे में पता होना चाहिए:

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

उपयोगकर्ताओं को बेहतर अनुभव देने के लिए, यहां दिए गए सबसे सही तरीके अपनाएं:

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

साइज़ के आधार पर कॉन्फ़िगरेशन में हुए बदलावों को हैंडल करना

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

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

साइज़ के आधार पर कॉन्फ़िगरेशन में होने वाले बदलावों के लिए, गतिविधि को फिर से बनाने की सुविधा को सीमित करें

साइज़ के आधार पर कॉन्फ़िगरेशन में बदलाव करने के लिए, Activity फिर से बनाने की सुविधा बंद करने पर, सिस्टम Activity को फिर से नहीं बनाता है. इसके बजाय, उसे Activity.onConfigurationChanged पर कॉल आता है. LocalConfiguration.current को पढ़ने वाले सभी कंपोज़ेबल, नए साइज़ को दिखाने के लिए अपने-आप फिर से कंपोज़ हो जाते हैं.

अगर आपकी मेनिफ़ेस्ट फ़ाइल में android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" मौजूद है, तो साइज़ के आधार पर कॉन्फ़िगरेशन में बदलाव करने पर, Activity को फिर से बनाने की सुविधा बंद हो जाती है.

अन्य संसाधन

कॉन्फ़िगरेशन में हुए बदलावों को मैनेज करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए अतिरिक्त संसाधन देखें:

दस्तावेज़

कॉन्टेंट देखना