सिद्धांत और Jetpack Compose को लागू करना
उपयोगकर्ता के आपके ऐप्लिकेशन को इस्तेमाल करने, नहीं करने, और वापस उसे शुरू करने पर, ऐप्लिकेशन में Activity इंस्टेंस की लाइफ़साइकल का अलग-अलग स्थितियों में ट्रांज़िशन होता है.
Activity क्लास, कई कॉलबैक उपलब्ध कराती है. इनकी मदद से, गतिविधि को यह पता चलता है कि स्थिति कब बदलती है या सिस्टम किसी गतिविधि को कब बनाता है, रोकता है या फिर से शुरू करता है. साथ ही, यह भी पता चलता है कि गतिविधि जिस प्रोसेस में मौजूद है उसे कब बंद किया जाता है.
लाइफ़साइकल कॉलबैक मैथड में, यह तय किया जा सकता है कि जब उपयोगकर्ता गतिविधि को छोड़ता है और फिर से उसमें शामिल होता है, तो आपकी गतिविधि कैसे काम करती है. उदाहरण के लिए, अगर आपको स्ट्रीमिंग वीडियो प्लेयर बनाना है, तो उपयोगकर्ता के किसी दूसरे ऐप्लिकेशन पर स्विच करने पर, वीडियो को रोका जा सकता है और नेटवर्क कनेक्शन को बंद किया जा सकता है. जब उपयोगकर्ता वापस आता है, तो नेटवर्क से फिर से कनेक्ट किया जा सकता है और उपयोगकर्ता को वीडियो को उसी जगह से फिर से शुरू करने की अनुमति दी जा सकती है.
हर कॉलबैक की मदद से, कोई खास काम किया जा सकता है. यह काम, स्थिति में हुए बदलाव के हिसाब से किया जाता है. सही समय पर सही काम करने और ट्रांज़िशन को सही तरीके से हैंडल करने से, आपका ऐप्लिकेशन ज़्यादा मज़बूत और बेहतर परफ़ॉर्म करता है. उदाहरण के लिए, लाइफ़साइकल कॉलबैक को सही तरीके से लागू करने से, आपका ऐप्लिकेशन इन समस्याओं से बच सकता है:
- अगर उपयोगकर्ता को आपका ऐप्लिकेशन इस्तेमाल करते समय फ़ोन कॉल आता है या वह किसी दूसरे ऐप्लिकेशन पर स्विच करता है, तो ऐप्लिकेशन क्रैश हो जाता है.
- जब उपयोगकर्ता इसका इस्तेमाल नहीं कर रहा होता है, तब भी यह सिस्टम के ज़रूरी संसाधनों का इस्तेमाल करता है.
- अगर उपयोगकर्ता आपके ऐप्लिकेशन को छोड़कर बाद में वापस आता है, तो उसकी प्रोग्रेस का डेटा मिट जाता है.
- स्क्रीन को लैंडस्केप और पोर्ट्रेट ओरिएंटेशन के बीच घुमाने पर, ऐप्लिकेशन क्रैश हो जाता है या उपयोगकर्ता की प्रोग्रेस सेव नहीं होती.
इस दस्तावेज़ में, गतिविधि की लाइफ़साइकल के बारे में पूरी जानकारी दी गई है. दस्तावेज़ में, लाइफ़साइकल पैराडाइम के बारे में बताया गया है. इसके बाद, इसमें हर कॉलबैक के बारे में बताया गया है: जब ये कॉलबैक लागू होते हैं, तब अंदरूनी तौर पर क्या होता है और आपको इनके दौरान क्या लागू करना होता है.
इसके बाद, इसमें गतिविधि की स्थिति और सिस्टम के ज़रिए प्रोसेस को बंद किए जाने की आशंका के बीच के संबंध के बारे में बताया गया है. आखिर में, इसमें गतिविधि की स्थितियों के बीच ट्रांज़िशन से जुड़े कई विषयों के बारे में बताया गया है.
लाइफ़साइकल मैनेज करने के बारे में जानकारी पाने के लिए, लाइफ़साइकल की जानकारी वाले कॉम्पोनेंट की मदद से लाइफ़साइकल मैनेज करना और यूज़र इंटरफ़ेस (यूआई) की स्थितियां सेव करना लेख पढ़ें. इनमें सबसे सही तरीकों के बारे में दिशा-निर्देश भी शामिल हैं. आर्किटेक्चर कॉम्पोनेंट के साथ-साथ ऐक्टिविटी का इस्तेमाल करके, प्रोडक्शन क्वालिटी वाला मज़बूत ऐप्लिकेशन बनाने का तरीका जानने के लिए, ऐप्लिकेशन आर्किटेक्चर की गाइड देखें.
ऐक्टिविटी लाइफ़साइकल के कॉन्सेप्ट
गतिविधि के लाइफ़साइकल के चरणों के बीच ट्रांज़िशन पर नेविगेट करने के लिए, Activity क्लास छह कॉलबैक का मुख्य सेट उपलब्ध कराती है: onCreate, onStart,
onResume, onPause, onStop, और onDestroy. जब ऐक्टिविटी नई स्थिति में जाती है, तब सिस्टम इनमें से हर कॉलबैक को शुरू करता है.
पहली इमेज में, इस पैराडाइम को विज़ुअल के तौर पर दिखाया गया है.
जब उपयोगकर्ता ऐक्टिविटी से बाहर निकलने लगता है, तो सिस्टम ऐक्टिविटी को बंद करने के लिए तरीकों को कॉल करता है. कुछ मामलों में, गतिविधि को सिर्फ़ कुछ हद तक बंद किया जाता है और वह अब भी मेमोरी में मौजूद रहती है. जैसे, जब उपयोगकर्ता किसी दूसरे ऐप्लिकेशन पर स्विच करता है. ऐसे मामलों में, गतिविधि अब भी फ़ोरग्राउंड में वापस आ सकती है.
अगर उपयोगकर्ता गतिविधि पर वापस आता है, तो वह वहीं से शुरू होती है जहां उपयोगकर्ता ने उसे छोड़ा था. कुछ अपवादों को छोड़कर, ऐप्लिकेशन को बैकग्राउंड में चलने के दौरान गतिविधियां शुरू करने से रोका जाता है.
सिस्टम किसी प्रोसेस को बंद कर सकता है. साथ ही, इसमें मौजूद गतिविधियों को भी बंद कर सकता है. हालांकि, ऐसा करने की संभावना इस बात पर निर्भर करती है कि उस समय गतिविधि की स्थिति क्या है. स्टेट और मेमोरी से हटाए जाने की संभावना के बीच के संबंध के बारे में ज़्यादा जानने के लिए, गतिविधि की स्थिति और मेमोरी से हटाए जाने की संभावना के बारे में सेक्शन देखें.
आपकी गतिविधि कितनी जटिल है, इस आधार पर हो सकता है कि आपको लाइफ़साइकल के सभी तरीकों को लागू करने की ज़रूरत न पड़े. हालांकि, यह ज़रूरी है कि आप हर एक को समझें और उन्हें लागू करें जो आपके ऐप्लिकेशन को उपयोगकर्ताओं की उम्मीद के मुताबिक काम करने में मदद करते हैं.
लाइफ़साइकल कॉलबैक
इस सेक्शन में, गतिविधि के लाइफ़साइकल के दौरान इस्तेमाल किए जाने वाले कॉलबैक तरीकों के बारे में कॉन्सेप्ट और लागू करने से जुड़ी जानकारी दी गई है.
कुछ कार्रवाइयां, ऐक्टिविटी के लाइफ़साइकल के तरीकों से जुड़ी होती हैं. हालांकि, डिपेंडेंट कॉम्पोनेंट के ऐक्शन लागू करने वाले कोड को कॉम्पोनेंट में रखें. इसे ऐक्टिविटी के लाइफ़साइकल वाले मैथड में न रखें. इसके लिए, आपको डिपेंडेंट कॉम्पोनेंट को लाइफ़साइकल की जानकारी वाला कॉम्पोनेंट बनाना होगा. डिपेंडेंट कॉम्पोनेंट को लाइफ़साइकल की जानकारी देने वाले कॉम्पोनेंट में बदलने का तरीका जानने के लिए, लाइफ़साइकल की जानकारी वाले कॉम्पोनेंट की मदद से लाइफ़साइकल मैनेज करना लेख पढ़ें.
onCreate
आपको इस कॉलबैक को लागू करना होगा. यह तब ट्रिगर होता है, जब सिस्टम पहली बार गतिविधि बनाता है. गतिविधि बनाने पर, गतिविधि बनाई गई स्थिति में आ जाती है. onCreate तरीके में, ऐप्लिकेशन के स्टार्टअप का बुनियादी लॉजिक लागू करें. यह लॉजिक, ऐक्टिविटी की पूरी लाइफ़साइकल में सिर्फ़ एक बार लागू होता है.
उदाहरण के लिए, onCreate को लागू करने पर, डेटा को सूचियों से बाइंड किया जा सकता है, गतिविधि को ViewModel से जोड़ा जा सकता है, और कुछ क्लास-स्कोप वाले वैरिएबल को इंस्टैंशिएट किया जा सकता है. इस तरीके को savedInstanceState पैरामीटर मिलता है. यह Bundle ऑब्जेक्ट होता है. इसमें गतिविधि की पहले से सेव की गई स्थिति होती है. अगर गतिविधि पहले कभी नहीं हुई है, तो Bundle
ऑब्जेक्ट की वैल्यू शून्य होती है.
अगर आपके पास लाइफ़साइकल की जानकारी वाला कोई ऐसा कॉम्पोनेंट है जो आपकी ऐक्टिविटी के लाइफ़साइकल से जुड़ा है, तो उसे ON_CREATE इवेंट मिलता है. @OnLifecycleEvent के साथ एनोटेट किए गए इस तरीके को इसलिए कॉल किया जाता है, ताकि लाइफ़साइकल की जानकारी रखने वाला कॉम्पोनेंट, क्रिएटेड स्टेट के लिए ज़रूरी सेटअप कोड को लागू कर सके.
onCreate तरीके के इस उदाहरण में, गतिविधि के लिए बुनियादी सेटअप दिखाया गया है. जैसे, यूज़र इंटरफ़ेस (एक्सएमएल लेआउट फ़ाइल में तय किया गया) का एलान करना, मेंबर वैरिएबल तय करना, और कुछ यूज़र इंटरफ़ेस को कॉन्फ़िगर करना. इस उदाहरण में, XML लेआउट फ़ाइल, फ़ाइल के संसाधन आईडी R.layout.main_activity को setContentView को पास करती है.
Kotlin
lateinit var textView: TextView
// Some transient state for the activity instance.
var gameState: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
// Call the superclass onCreate to complete the creation of
// the activity, like the view hierarchy.
super.onCreate(savedInstanceState)
// Recover the instance state.
gameState = savedInstanceState?.getString(GAME_STATE_KEY)
// Set the user interface layout for this activity.
// The layout is defined in the project res/layout/main_activity.xml file.
setContentView(R.layout.main_activity)
// Initialize member TextView so it is available later.
textView = findViewById(R.id.text_view)
}
// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}
// Invoked when the activity might be temporarily destroyed; save the instance state here.
override fun onSaveInstanceState(outState: Bundle?) {
outState?.run {
putString(GAME_STATE_KEY, gameState)
putString(TEXT_VIEW_KEY, textView.text.toString())
}
// Call superclass to save any view hierarchy.
super.onSaveInstanceState(outState)
}
Java
TextView textView;
// Some transient state for the activity instance.
String gameState;
@Override
public void onCreate(Bundle savedInstanceState) {
// Call the superclass onCreate to complete the creation of
// the activity, like the view hierarchy.
super.onCreate(savedInstanceState);
// Recover the instance state.
if (savedInstanceState != null) {
gameState = savedInstanceState.getString(GAME_STATE_KEY);
}
// Set the user interface layout for this activity.
// The layout is defined in the project res/layout/main_activity.xml file.
setContentView(R.layout.main_activity);
// Initialize member TextView so it is available later.
textView = (TextView) findViewById(R.id.text_view);
}
// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}
// Invoked when the activity might be temporarily destroyed; save the instance state here.
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(GAME_STATE_KEY, gameState);
outState.putString(TEXT_VIEW_KEY, textView.getText());
// Call superclass to save any view hierarchy.
super.onSaveInstanceState(outState);
}
एक्सएमएल फ़ाइल को तय करने और उसे setContentView में पास करने के बजाय, अपनी ऐक्टिविटी के कोड में नए View ऑब्जेक्ट बनाए जा सकते हैं. साथ ही, ViewGroup में नए View ऑब्जेक्ट डालकर, व्यू हैरारकी बनाई जा सकती है. इसके बाद, रूट ViewGroup को setContentView में पास करके, उस लेआउट का इस्तेमाल किया जाता है. यूज़र इंटरफ़ेस बनाने के बारे में ज़्यादा जानने के लिए, यूज़र इंटरफ़ेस से जुड़ा दस्तावेज़ देखें.
आपकी गतिविधि, तय की गई स्थिति में नहीं रहती है. onCreate तरीके के लागू होने के बाद, गतिविधि शुरू की गई स्थिति में जाती है. इसके बाद, सिस्टम onStart और onResume तरीकों को तुरंत शुरू करता है.
onStart
जब गतिविधि 'शुरू की गई' स्थिति में जाती है, तब सिस्टम onStart को शुरू करता है.
इस कॉल से, उपयोगकर्ता को गतिविधि दिखने लगती है. ऐसा तब होता है, जब ऐप्लिकेशन गतिविधि को फ़ोरग्राउंड में लाने और उसे इंटरैक्टिव बनाने की तैयारी करता है. उदाहरण के लिए, इस
तरीके में, यूज़र इंटरफ़ेस (यूआई) को बनाए रखने वाले कोड को शुरू किया जाता है.
जब ऐक्टिविटी, 'शुरू की गई' स्थिति में पहुंच जाती है, तब लाइफ़साइकल के बारे में जानकारी रखने वाला कोई भी कॉम्पोनेंट, ऐक्टिविटी के लाइफ़साइकल से जुड़ा होता है. इसे ON_START इवेंट मिलता है.
onStart मेथड तुरंत पूरा हो जाता है. साथ ही, Created स्टेट की तरह, ऐक्टिविटी Started स्टेट में नहीं रहती है. यह कॉलबैक पूरा होने के बाद, गतिविधि Resumed स्थिति में आ जाती है. इसके बाद, सिस्टम onResume तरीके को शुरू करता है.
onResume
जब गतिविधि 'फिर शुरू करें' वाली स्थिति में जाती है, तब यह फ़ोरग्राउंड में आ जाती है. इसके बाद, सिस्टम onResume कॉलबैक को शुरू करता है. यह वह स्थिति होती है जिसमें ऐप्लिकेशन, उपयोगकर्ता के साथ इंटरैक्ट करता है. ऐप्लिकेशन तब तक इस स्थिति में रहता है, जब तक कोई ऐसी गतिविधि नहीं होती जिससे ऐप्लिकेशन पर फ़ोकस हट जाए. जैसे, डिवाइस पर फ़ोन कॉल आना, उपयोगकर्ता का किसी दूसरी गतिविधि पर जाना या डिवाइस की स्क्रीन बंद होना.
जब गतिविधि, 'फिर शुरू करें' वाली स्थिति में जाती है, तब लाइफ़साइकल के बारे में जानकारी रखने वाले किसी भी कॉम्पोनेंट को ON_RESUME इवेंट मिलता है. यह कॉम्पोनेंट, गतिविधि के लाइफ़साइकल से जुड़ा होता है. लाइफ़साइकल कॉम्पोनेंट, ऐसी किसी भी सुविधा को चालू कर सकते हैं जिसे कॉम्पोनेंट के दिखने और फ़ोरग्राउंड में होने के दौरान चलाने की ज़रूरत होती है. जैसे, कैमरे की झलक दिखाना.
जब कोई रुकावट डालने वाला इवेंट होता है, तब गतिविधि रोकी गई स्थिति में चली जाती है. साथ ही, सिस्टम onPause कॉलबैक को शुरू करता है.
अगर गतिविधि, रोकी गई स्थिति से फिर शुरू की गई स्थिति में वापस आती है, तो सिस्टम एक बार फिर onResume मैथड को कॉल करता है. इसलिए, onResume का इस्तेमाल करें. इससे onPause के दौरान रिलीज़ किए गए कॉम्पोनेंट को शुरू किया जा सकता है. साथ ही, अन्य शुरुआती प्रोसेस भी पूरी की जा सकती हैं. ये प्रोसेस, गतिविधि के फिर से शुरू होने की स्थिति में आने पर हर बार होनी चाहिए.
यहां लाइफ़साइकल की जानकारी वाले कॉम्पोनेंट का एक उदाहरण दिया गया है. यह कॉम्पोनेंट, ON_RESUME इवेंट मिलने पर कैमरे को ऐक्सेस करता है:
Kotlin
class CameraComponent : LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun initializeCamera() {
if (camera == null) {
getCamera()
}
}
...
}
Java
public class CameraComponent implements LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void initializeCamera() {
if (camera == null) {
getCamera();
}
}
...
}
ऊपर दिया गया कोड, LifecycleObserver को ON_RESUME इवेंट मिलने के बाद, कैमरे को एक बार चालू करता है. हालांकि, मल्टी-विंडो मोड में, आपकी गतिविधि पूरी तरह से दिख सकती है. भले ही, वह रुकी हुई स्थिति में हो. उदाहरण के लिए, जब ऐप्लिकेशन मल्टी-विंडो मोड में होता है और उपयोगकर्ता उस विंडो पर टैप करता है जिसमें आपकी गतिविधि नहीं होती है, तो आपकी गतिविधि 'रोका गया' स्थिति में चली जाती है.
अगर आपको कैमरा सिर्फ़ तब चालू रखना है, जब ऐप्लिकेशन फिर से शुरू हो (दिख रहा हो और फ़ोरग्राउंड में चालू हो), तो ON_RESUME इवेंट के बाद कैमरा शुरू करें. इस इवेंट के बारे में पहले बताया जा चुका है. अगर आपको गतिविधि के रुकने के दौरान भी कैमरे को चालू रखना है, लेकिन उसे दिखाना है, जैसे कि मल्टी-विंडो मोड में, तो ON_START इवेंट के बाद कैमरे को शुरू करें.
हालांकि, गतिविधि के रुकने के दौरान कैमरा चालू रखने से, मल्टी-विंडो मोड में फिर से शुरू किए गए किसी दूसरे ऐप्लिकेशन को कैमरे का ऐक्सेस नहीं मिल सकता. कभी-कभी, गतिविधि के रुके होने पर भी कैमरे को चालू रखना ज़रूरी होता है. हालांकि, ऐसा करने से उपयोगकर्ता अनुभव खराब हो सकता है.
इसलिए, सोच-समझकर तय करें कि मल्टी-विंडो मोड के संदर्भ में, शेयर किए गए सिस्टम संसाधनों का कंट्रोल कब लेना सबसे सही होगा. मल्टी-विंडो मोड के बारे में ज़्यादा जानने के लिए, मल्टी-विंडो मोड के साथ काम करना लेख पढ़ें.
चाहे आपने किसी भी बिल्ड-अप इवेंट में इनिशियलाइज़ेशन की कार्रवाई की हो, संसाधन को रिलीज़ करने के लिए उससे जुड़े लाइफ़साइकल इवेंट का इस्तेमाल करना न भूलें. अगर आपने ON_START इवेंट के बाद कोई कार्रवाई शुरू की है, तो उसे ON_STOP इवेंट के बाद ही रिलीज़ या खत्म करें. अगर आपने ON_RESUME इवेंट के बाद शुरू किया है, तो ON_PAUSE इवेंट के बाद रिलीज़ करें.
ऊपर दिए गए कोड स्निपेट में, कैमरा शुरू करने के कोड को लाइफ़साइकल के बारे में जानने वाले कॉम्पोनेंट में रखा गया है. इसके बजाय, इस कोड को सीधे तौर पर गतिविधि के लाइफ़साइकल कॉलबैक में डाला जा सकता है. जैसे, onStart और onStop. हालांकि, हम ऐसा करने का सुझाव नहीं देते. इस लॉजिक को लाइफ़साइकल की जानकारी वाले किसी स्वतंत्र कॉम्पोनेंट में जोड़ने से, आपको कोड को डुप्लीकेट किए बिना, कॉम्पोनेंट को कई गतिविधियों में फिर से इस्तेमाल करने की सुविधा मिलती है. लाइफ़साइकल की जानकारी वाला कॉम्पोनेंट बनाने का तरीका जानने के लिए, लाइफ़साइकल की जानकारी वाले कॉम्पोनेंट (व्यू) की मदद से लाइफ़साइकल मैनेज करना लेख पढ़ें.
onPause
सिस्टम इस तरीके को पहली बार तब कॉल करता है, जब उपयोगकर्ता आपकी गतिविधि छोड़ रहा होता है. हालांकि, इसका यह मतलब हमेशा नहीं होता कि गतिविधि को बंद किया जा रहा है. इससे पता चलता है कि गतिविधि अब फ़ोरग्राउंड में नहीं है. हालांकि, अगर उपयोगकर्ता मल्टी-विंडो मोड में है, तो यह अब भी दिखती है. किसी गतिविधि के इस स्थिति में पहुंचने की कई वजहें हो सकती हैं:
- ऐसा इवेंट जो ऐप्लिकेशन के एक्ज़ीक्यूशन में रुकावट डालता है.
onResumeकॉलबैक के बारे में बताए गए सेक्शन में इसके बारे में बताया गया है. इससे मौजूदा गतिविधि रुक जाती है. यह सबसे सामान्य मामला है. - मल्टी-विंडो मोड में, किसी भी समय सिर्फ़ एक ऐप्लिकेशन पर फ़ोकस किया जाता है. साथ ही, सिस्टम अन्य सभी ऐप्लिकेशन को रोक देता है.
- डायलॉग बॉक्स जैसी नई और कुछ हद तक पारदर्शी गतिविधि खुलने पर, उसके पीछे मौजूद गतिविधि रुक जाती है. जब तक गतिविधि आंशिक रूप से दिखती है, लेकिन फ़ोकस में नहीं होती, तब तक वह रुकी रहती है.
जब कोई गतिविधि Paused स्थिति में चली जाती है, तब गतिविधि के लाइफ़साइकल से जुड़ा कोई भी लाइफ़साइकल-अवेयर कॉम्पोनेंट, ON_PAUSE इवेंट को पाता है. लाइफ़साइकल कॉम्पोनेंट, ऐसी किसी भी सुविधा को बंद कर सकते हैं जिसे कॉम्पोनेंट के फ़ोरग्राउंड में न होने पर चलाने की ज़रूरत नहीं होती. जैसे, कैमरे की झलक को रोकना.
onPause तरीके का इस्तेमाल करके, उन कार्रवाइयों को रोकें या उनमें बदलाव करें जिन्हें Activity के रुके हुए होने के दौरान जारी नहीं रखा जा सकता या जिन्हें कुछ समय के लिए जारी रखा जा सकता है. साथ ही, जिन्हें आपको जल्द ही फिर से शुरू करना है.
सिस्टम के संसाधनों, सेंसर (जैसे, जीपीएस) के हैंडल या बैटरी लाइफ़ पर असर डालने वाले किसी भी संसाधन को रिलीज़ करने के लिए, onPause तरीके का इस्तेमाल किया जा सकता है. ऐसा तब करें, जब आपकी गतिविधि रुकी हुई हो और उपयोगकर्ता को उनकी ज़रूरत न हो.
हालांकि, onResume सेक्शन में बताया गया है कि अगर ऐप्लिकेशन मल्टी-विंडो मोड में है, तो रुकी हुई गतिविधि अब भी पूरी तरह से दिख सकती है. मल्टी-विंडो मोड को बेहतर तरीके से सपोर्ट करने के लिए, यूज़र इंटरफ़ेस (यूआई) से जुड़े संसाधनों और कार्रवाइयों को पूरी तरह से रिलीज़ करने या उनमें बदलाव करने के लिए, onPause के बजाय onStop का इस्तेमाल करें.
यहां ON_PAUSE इवेंट पर प्रतिक्रिया करने वाले LifecycleObserver का उदाहरण दिया गया है. यह ON_RESUME इवेंट के पिछले उदाहरण के जैसा ही है. इसमें ON_RESUME इवेंट मिलने के बाद, कैमरा शुरू होता है:
Kotlin
class CameraComponent : LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun releaseCamera() {
camera?.release()
camera = null
}
...
}
Java
public class JavaCameraComponent implements LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void releaseCamera() {
if (camera != null) {
camera.release();
camera = null;
}
}
...
}
इस उदाहरण में, ON_PAUSE इवेंट के LifecycleObserver को मिलने के बाद, कैमरा रिलीज़ कोड रखा गया है.
onPause को बहुत कम समय के लिए लागू किया जाता है. इसलिए, ज़रूरी नहीं है कि सेव करने की कार्रवाइयां पूरी करने के लिए, आपके पास काफ़ी समय हो. इस वजह से, ऐप्लिकेशन या उपयोगकर्ता का डेटा सेव करने, नेटवर्क कॉल करने या डेटाबेस के लेन-देन को पूरा करने के लिए, onPause का इस्तेमाल न करें.
ऐसा हो सकता है कि यह काम, तरीके के पूरा होने से पहले पूरा न हो.
इसके बजाय, शटडाउन से जुड़ी ज़्यादा लोड वाली कार्रवाइयां onStop के दौरान करें. onStop के दौरान किए जाने वाले सही ऑपरेशनों के बारे में ज़्यादा जानकारी के लिए, अगला सेक्शन देखें. डेटा सेव करने के बारे में ज़्यादा जानकारी के लिए, स्टेट सेव करना और उसे वापस लाना सेक्शन देखें.
onPause तरीके के पूरा होने का मतलब यह नहीं है कि गतिविधि, रुकी हुई स्थिति से बाहर निकल गई है. इसके बजाय, गतिविधि तब तक इस स्थिति में रहती है, जब तक गतिविधि फिर से शुरू नहीं हो जाती या उपयोगकर्ता को पूरी तरह से नहीं दिखती. अगर गतिविधि फिर से शुरू होती है, तो सिस्टम एक बार फिर onResume कॉलबैक को शुरू करता है.
अगर गतिविधि, रोकी गई स्थिति से फिर से शुरू की गई स्थिति में वापस आती है, तो सिस्टम Activity इंस्टेंस को मेमोरी में सेव रखता है. जब सिस्टम onResume को शुरू करता है, तब वह इंस्टेंस को वापस लाता है. इस स्थिति में, आपको Resumed स्थिति तक पहुंचने से पहले, किसी भी कॉलबैक तरीके के दौरान बनाए गए कॉम्पोनेंट को फिर से शुरू करने की ज़रूरत नहीं होती. अगर गतिविधि पूरी तरह से दिखनी बंद हो जाती है, तो सिस्टम onStop को कॉल करता है.
onStop
जब आपकी गतिविधि उपयोगकर्ता को नहीं दिखती है, तब वह Stopped
स्टेट में चली जाती है. साथ ही, सिस्टम onStop कॉलबैक को शुरू करता है. ऐसा तब हो सकता है, जब हाल ही में लॉन्च की गई कोई गतिविधि पूरी स्क्रीन पर दिख रही हो. सिस्टम, ऐक्टिविटी के बंद होने से पहले onStop को भी कॉल करता है.
जब ऐक्टिविटी को Stopped स्थिति में ले जाया जाता है, तब ऐक्टिविटी के लाइफ़साइकल से जुड़ा कोई भी लाइफ़साइकल-अवेयर कॉम्पोनेंट, ON_STOP इवेंट को पाता है. लाइफ़साइकल कॉम्पोनेंट, यहां ऐसी किसी भी सुविधा को रोक सकते हैं जिसे कॉम्पोनेंट के स्क्रीन पर न दिखने के दौरान चलाने की ज़रूरत नहीं होती.
onStop तरीके में, उन संसाधनों को रिलीज़ या अडजस्ट करें जिनकी ज़रूरत तब नहीं होती, जब ऐप्लिकेशन उपयोगकर्ता को नहीं दिख रहा होता है. उदाहरण के लिए, आपका ऐप्लिकेशन ऐनिमेशन को रोक सकता है या जगह की सटीक जानकारी के बजाय अनुमानित जानकारी को अपडेट करने पर स्विच कर सकता है. onPause के बजाय onStop का इस्तेमाल करने का मतलब है कि यूज़र इंटरफ़ेस (यूआई) से जुड़ा काम जारी रहता है. भले ही, उपयोगकर्ता मल्टी-विंडो मोड में आपकी गतिविधि देख रहा हो.
इसके अलावा, सीपीयू का ज़्यादा इस्तेमाल करने वाली शटडाउन कार्रवाइयां करने के लिए, onStop का इस्तेमाल करें. उदाहरण के लिए, अगर आपको डेटाबेस में जानकारी सेव करने का कोई बेहतर समय नहीं मिल रहा है, तो हो सकता है कि आप ऐसा onStop के दौरान करें. यहां onStop को लागू करने का एक उदाहरण दिया गया है. इसमें, ड्राफ़्ट नोट के कॉन्टेंट को परसिस्टेंट स्टोरेज में सेव किया जाता है:
Kotlin
override fun onStop() {
// Call the superclass method first.
super.onStop()
// Save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
val values = ContentValues().apply {
put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
}
// Do this update in background on an AsyncQueryHandler or equivalent.
asyncQueryHandler.startUpdate(
token, // int token to correlate calls
null, // cookie, not used here
uri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
)
}
Java
@Override
protected void onStop() {
// Call the superclass method first.
super.onStop();
// Save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
// Do this update in background on an AsyncQueryHandler or equivalent.
asyncQueryHandler.startUpdate (
mToken, // int token to correlate calls
null, // cookie, not used here
uri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}
ऊपर दिए गए कोड के सैंपल में, सीधे तौर पर SQLite का इस्तेमाल किया गया है. हालांकि, हमारा सुझाव है कि आप Room का इस्तेमाल करें. यह एक परसिस्टेंस लाइब्रेरी है, जो SQLite को लेकर एक ऐब्स्ट्रैक्शन लेयर उपलब्ध कराती है. Room का इस्तेमाल करने के फ़ायदों और इसे अपने ऐप्लिकेशन में लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, Room परसिस्टेंस लाइब्रेरी गाइड देखें.
जब आपकी गतिविधि, 'बंद है' स्थिति में पहुंच जाती है, तो Activity ऑब्जेक्ट को मेमोरी में सेव रखा जाता है. यह सभी स्थितियों और सदस्यों की जानकारी को बनाए रखता है, लेकिन विंडो मैनेजर से अटैच नहीं होता है. गतिविधि फिर से शुरू होने पर, यह जानकारी वापस आ जाती है.
आपको Resumed स्टेट तक पहुंचने के लिए, किसी भी कॉलबैक तरीके के दौरान बनाए गए कॉम्पोनेंट को फिर से शुरू करने की ज़रूरत नहीं है. सिस्टम, लेआउट में मौजूद हर View ऑब्जेक्ट की मौजूदा स्थिति को भी ट्रैक करता है. इसलिए, अगर उपयोगकर्ता किसी EditText विजेट में टेक्स्ट डालता है, तो उस कॉन्टेंट को सेव करके रखा जाता है. इससे आपको उसे सेव और रीस्टोर करने की ज़रूरत नहीं पड़ती.
बंद की गई गतिविधि, उपयोगकर्ता के साथ इंटरैक्ट करने के लिए वापस आ जाती है या गतिविधि पूरी हो जाती है और बंद हो जाती है. अगर गतिविधि वापस आती है, तो सिस्टम onRestart को शुरू करता है. अगर Activity का काम पूरा हो जाता है, तो सिस्टम onDestroy को कॉल करता है.
onDestroy
onDestroy को गतिविधि खत्म होने से पहले कॉल किया जाता है. सिस्टम, इन दो में से किसी एक वजह से इस कॉलबैक को शुरू करता है:
- उपयोगकर्ता के गतिविधि को पूरी तरह से खारिज करने या गतिविधि पर
finishको कॉल करने की वजह से, गतिविधि खत्म हो रही है. - सिस्टम, कॉन्फ़िगरेशन में बदलाव होने की वजह से गतिविधि को कुछ समय के लिए बंद कर रहा है. जैसे, डिवाइस को घुमाना या मल्टी-विंडो मोड में जाना.
जब गतिविधि, खत्म की गई स्थिति में चली जाती है, तब गतिविधि के लाइफ़साइकल से जुड़े लाइफ़साइकल के बारे में जानकारी रखने वाले किसी भी कॉम्पोनेंट को ON_DESTROY इवेंट मिलता है. लाइफ़साइकल कॉम्पोनेंट, Activity के बंद होने से पहले, यहां अपनी ज़रूरत की चीज़ों को हटा सकते हैं.
Activity में लॉजिक डालने के बजाय, ViewModel ऑब्जेक्ट का इस्तेमाल करें. इससे यह तय किया जा सकेगा कि Activity को क्यों हटाया जा रहा है. साथ ही, Activity के लिए काम का व्यू डेटा भी शामिल किया जा सकेगा. अगर कॉन्फ़िगरेशन में बदलाव की वजह से Activity को फिर से बनाया जाता है, तो ViewModel को कुछ भी करने की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि इसे सुरक्षित रखा जाता है और अगले Activity इंस्टेंस को दिया जाता है.
अगर Activity को फिर से नहीं बनाया जाता है, तो Activity में onCleared मैथड को कॉल किया जाता है. इससे, डिस्ट्रॉय होने से पहले, Activity को ज़रूरी डेटा को क्लीन अप करने का मौका मिलता है.ViewModel isFinishing तरीके का इस्तेमाल करके, इन दोनों स्थितियों के बीच अंतर किया जा सकता है.
अगर गतिविधि खत्म हो रही है, तो onDestroy, लाइफ़साइकल का आखिरी कॉलबैक है. अगर कॉन्फ़िगरेशन में बदलाव होने की वजह से onDestroy को कॉल किया जाता है, तो सिस्टम तुरंत एक नया गतिविधि इंस्टेंस बनाता है. इसके बाद, नए कॉन्फ़िगरेशन में उस नए इंस्टेंस पर onCreate को कॉल करता है.
onDestroy कॉलबैक, उन सभी संसाधनों को रिलीज़ करता है जिन्हें पहले के कॉलबैक ने रिलीज़ नहीं किया था. जैसे, onStop.
ट्रांज़िएंट यूज़र इंटरफ़ेस (यूआई) की स्थिति को सेव करना और वापस लाना
कोई उपयोगकर्ता यह उम्मीद करता है कि कॉन्फ़िगरेशन में होने वाले बदलाव के दौरान, किसी गतिविधि के यूज़र इंटरफ़ेस (यूआई) की स्थिति में कोई बदलाव न हो. जैसे, डिवाइस को घुमाने या मल्टी-विंडो मोड में स्विच करने के दौरान. हालांकि, इस तरह के कॉन्फ़िगरेशन में बदलाव होने पर, सिस्टम डिफ़ॉल्ट रूप से ऐक्टिविटी को बंद कर देता है. इससे ऐक्टिविटी इंस्टेंस में सेव किया गया यूज़र इंटरफ़ेस (यूआई) स्टेट मिट जाता है.
इसी तरह, अगर कोई उपयोगकर्ता कुछ समय के लिए आपके ऐप्लिकेशन से किसी दूसरे ऐप्लिकेशन पर स्विच करता है और फिर बाद में आपके ऐप्लिकेशन पर वापस आता है, तो वह यह उम्मीद करता है कि यूज़र इंटरफ़ेस (यूआई) की स्थिति पहले जैसी ही बनी रहेगी. हालांकि, जब उपयोगकर्ता डिवाइस का इस्तेमाल नहीं कर रहा होता है और आपकी ऐक्टिविटी बंद हो जाती है, तब सिस्टम आपके ऐप्लिकेशन की प्रोसेस को बंद कर सकता है.
जब सिस्टम की सीमाओं की वजह से गतिविधि बंद हो जाती है, तब ViewModel, onSaveInstanceState, और/या लोकल स्टोरेज का इस्तेमाल करके, उपयोगकर्ता के यूज़र इंटरफ़ेस (यूआई) की अस्थायी स्थिति को बनाए रखें. सिस्टम के व्यवहार की तुलना में उपयोगकर्ता की उम्मीदों के बारे में ज़्यादा जानने के लिए, यूज़र इंटरफ़ेस की स्थितियां सेव करना लेख पढ़ें. इसमें यह भी बताया गया है कि सिस्टम की ओर से शुरू की गई गतिविधि और प्रोसेस के बंद होने पर, यूज़र इंटरफ़ेस की स्थिति के जटिल डेटा को सबसे सही तरीके से कैसे सुरक्षित रखा जाए.
इस सेक्शन में बताया गया है कि इंस्टेंस की स्थिति क्या होती है और onSaveInstance तरीके को कैसे लागू किया जाता है. यह तरीका, गतिविधि पर कॉलबैक होता है. अगर आपका यूज़र इंटरफ़ेस (यूआई) डेटा हल्का है, तो कॉन्फ़िगरेशन में बदलाव होने और सिस्टम की वजह से प्रोसेस बंद होने, दोनों ही स्थितियों में यूज़र इंटरफ़ेस (यूआई) की स्थिति को बनाए रखने के लिए, सिर्फ़ onSaveInstance का इस्तेमाल किया जा सकता है. हालांकि, onSaveInstance में सीरियलाइज़ेशन/डीसीरियलाइज़ेशन का शुल्क लगता है. इसलिए, ज़्यादातर मामलों में ViewModel और onSaveInstance, दोनों का इस्तेमाल किया जाता है. इसके बारे में यूज़र इंटरफ़ेस (यूआई) की स्थितियां सेव करना लेख में बताया गया है.
इंस्टेंस की स्थिति
कुछ ऐसे मामले होते हैं जिनमें ऐप्लिकेशन के सामान्य व्यवहार की वजह से आपकी गतिविधि बंद हो जाती है. जैसे, जब उपयोगकर्ता 'वापस जाएं' बटन दबाता है या आपकी गतिविधि, finish तरीके को कॉल करके खुद को बंद करने का सिग्नल देती है.
जब उपयोगकर्ता'वापस जाएं' बटन दबाता है या ऐक्टिविटी अपने-आप खत्म हो जाती है, तो सिस्टम और उपयोगकर्ता, दोनों के लिए उस Activity इंस्टेंस का कॉन्सेप्ट हमेशा के लिए खत्म हो जाता है. इन स्थितियों में, उपयोगकर्ता की उम्मीदें सिस्टम के व्यवहार से मेल खाती हैं. इसलिए, आपको कुछ और करने की ज़रूरत नहीं होती.
हालांकि, अगर सिस्टम की सीमाओं (जैसे कि कॉन्फ़िगरेशन में बदलाव या मेमोरी पर दबाव) की वजह से गतिविधि खत्म हो जाती है, तो Activity का मौजूदा इंस्टेंस खत्म हो जाता है. हालांकि, सिस्टम को यह याद रहता है कि यह इंस्टेंस मौजूद था. अगर उपयोगकर्ता गतिविधि पर वापस जाने की कोशिश करता है, तो सिस्टम उस गतिविधि का नया इंस्टेंस बनाता है. इसके लिए, वह सेव किए गए डेटा के उस सेट का इस्तेमाल करता है जिसमें गतिविधि के बंद होने की स्थिति के बारे में बताया गया होता है.
सेव किए गए जिस डेटा का इस्तेमाल करके सिस्टम पिछली स्थिति को वापस लाता है उसे इंस्टेंस की स्थिति कहा जाता है. यह Bundle ऑब्जेक्ट में सेव किए गए की-वैल्यू पेयर का कलेक्शन होता है. डिफ़ॉल्ट रूप से, सिस्टम Bundle इंस्टेंस की स्थिति का इस्तेमाल करता है. इससे आपकी गतिविधि के लेआउट में मौजूद हर View ऑब्जेक्ट के बारे में जानकारी सेव की जाती है. जैसे, EditText विजेट में डाली गई टेक्स्ट वैल्यू.
इसलिए, अगर आपकी गतिविधि का इंस्टेंस मिट जाता है और उसे फिर से बनाया जाता है, तो लेआउट की स्थिति को उसकी पिछली स्थिति में वापस ला दिया जाता है. इसके लिए, आपको किसी कोड की ज़रूरत नहीं होती. हालांकि, आपकी गतिविधि में ऐसी ज़्यादा जानकारी हो सकती है जिसे आपको वापस लाना हो. जैसे, सदस्य वैरिएबल, जो गतिविधि में उपयोगकर्ता की प्रोग्रेस को ट्रैक करते हैं.
Bundle ऑब्जेक्ट, बहुत कम डेटा को सेव करने के लिए सही नहीं है. ऐसा इसलिए, क्योंकि इसके लिए मुख्य थ्रेड पर क्रम से लगाने की ज़रूरत होती है. साथ ही, यह सिस्टम-प्रोसेस की मेमोरी का इस्तेमाल करता है. बहुत कम डेटा के अलावा, ज़्यादा डेटा को बनाए रखने के लिए, डेटा को बनाए रखने के लिए एक साथ कई तरीकों का इस्तेमाल करें. जैसे, परसिस्टेंट लोकल स्टोरेज, onSaveInstanceState तरीका, और ViewModel क्लास. इनके बारे में यूज़र इंटरफ़ेस (यूआई) की स्थितियां सेव करना लेख में बताया गया है.
onSaveInstanceState का इस्तेमाल करके, आसान और कम मेमोरी लेने वाली यूज़र इंटरफ़ेस (यूआई) की स्थिति सेव करना
जब आपकी गतिविधि बंद होने लगती है, तब सिस्टम onSaveInstanceState तरीके को कॉल करता है, ताकि आपकी गतिविधि, इंस्टेंस की स्थिति वाले बंडल में स्थिति की जानकारी सेव कर सके. इस तरीके को डिफ़ॉल्ट रूप से लागू करने पर, गतिविधि की व्यू हैरारकी की स्थिति के बारे में कुछ समय के लिए जानकारी सेव की जाती है. जैसे, EditText विजेट में मौजूद टेक्स्ट या ListView विजेट की स्क्रोल पोज़िशन.
अपनी गतिविधि के लिए इंस्टेंस की स्थिति के बारे में अतिरिक्त जानकारी सेव करने के लिए, onSaveInstanceState को बदलें और Bundle ऑब्जेक्ट में की-वैल्यू पेयर जोड़ें. यह ऑब्जेक्ट, आपकी गतिविधि के अचानक बंद होने पर सेव किया जाता है. onSaveInstanceState को ओवरराइड करते समय, आपको सुपरक्लास के इंप्लिमेंटेशन को कॉल करना होगा. ऐसा तब करें, जब आपको व्यू हैरारकी की स्थिति को सेव करने के लिए डिफ़ॉल्ट इंप्लिमेंटेशन की ज़रूरत हो.
इसे यहां दिए गए उदाहरण में दिखाया गया है:
Kotlin
override fun onSaveInstanceState(outState: Bundle?) {
// Save the user's current game state.
outState?.run {
putInt(STATE_SCORE, currentScore)
putInt(STATE_LEVEL, currentLevel)
}
// Always call the superclass so it can save the view hierarchy state.
super.onSaveInstanceState(outState)
}
companion object {
val STATE_SCORE = "playerScore"
val STATE_LEVEL = "playerLevel"
}
Java
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state.
savedInstanceState.putInt(STATE_SCORE, currentScore);
savedInstanceState.putInt(STATE_LEVEL, currentLevel);
// Always call the superclass so it can save the view hierarchy state.
super.onSaveInstanceState(savedInstanceState);
}
हमेशा मौजूद रहने वाले डेटा को सेव करने के लिए, सही समय पर कार्रवाई करें. जैसे, उपयोगकर्ता की प्राथमिकताएं या डेटाबेस के लिए डेटा. अगर ऐसा कोई मौका नहीं मिलता है, तो onStop तरीके के दौरान लगातार डेटा सेव करें.
सेव किए गए इंस्टेंस की स्थिति का इस्तेमाल करके, गतिविधि के यूज़र इंटरफ़ेस (यूआई) की स्थिति को वापस लाना
जब आपकी गतिविधि को पहले मिटाने के बाद फिर से बनाया जाता है, तब सेव की गई इंस्टेंस की स्थिति को वापस लाया जा सकता है. इसके लिए, Bundle का इस्तेमाल करें. यह ऑब्जेक्ट, सिस्टम आपकी गतिविधि को पास करता है. onCreate और onRestoreInstanceState, दोनों कॉलबैक तरीकों को एक ही Bundle मिलता है. इसमें इंस्टेंस की स्थिति की जानकारी होती है.
onCreate तरीके को तब कॉल किया जाता है, जब सिस्टम आपकी गतिविधि का नया इंस्टेंस बनाता है या पिछले इंस्टेंस को फिर से बनाता है. इसलिए, आपको यह जांच करनी होगी कि Bundle की स्थिति शून्य है या नहीं. इसके बाद ही, इसे पढ़ा जा सकता है. अगर यह शून्य है, तो सिस्टम गतिविधि का नया इंस्टेंस बना रहा है. ऐसा इसलिए, क्योंकि वह गतिविधि के उस पिछले इंस्टेंस को वापस नहीं ला सकता जिसे खत्म कर दिया गया था.
नीचे दिए गए कोड स्निपेट में दिखाया गया है कि onCreate में कुछ स्टेट डेटा को कैसे वापस लाया जा सकता है:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) // Always call the superclass first
// Check whether we're recreating a previously destroyed instance.
if (savedInstanceState != null) {
with(savedInstanceState) {
// Restore value of members from saved state.
currentScore = getInt(STATE_SCORE)
currentLevel = getInt(STATE_LEVEL)
}
} else {
// Probably initialize members with default values for a new instance.
}
// ...
}
Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance.
if (savedInstanceState != null) {
// Restore value of members from saved state.
currentScore = savedInstanceState.getInt(STATE_SCORE);
currentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance.
}
// ...
}
onCreate के दौरान स्थिति को वापस लाने के बजाय, onRestoreInstanceState को लागू किया जा सकता है. सिस्टम इसे onStart तरीके के बाद कॉल करता है. सिस्टम, onRestoreInstanceState को सिर्फ़ तब कॉल करता है, जब सेव की गई कोई ऐसी स्थिति हो जिसे वापस लाना हो. इसलिए, आपको यह देखने की ज़रूरत नहीं है कि Bundle शून्य है या नहीं.
Kotlin
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
// Always call the superclass so it can restore the view hierarchy.
super.onRestoreInstanceState(savedInstanceState)
// Restore state members from saved instance.
savedInstanceState?.run {
currentScore = getInt(STATE_SCORE)
currentLevel = getInt(STATE_LEVEL)
}
}
Java
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy.
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance.
currentScore = savedInstanceState.getInt(STATE_SCORE);
currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
ऐक्टिविटी के बीच नेविगेट करना
ऐप्लिकेशन की लाइफ़टाइम के दौरान, ऐप्लिकेशन कई बार किसी गतिविधि में शामिल हो सकता है और उससे बाहर निकल सकता है. जैसे, जब उपयोगकर्ता डिवाइस के'वापस जाएं' बटन पर टैप करता है या गतिविधि किसी दूसरी गतिविधि को लॉन्च करती है.
इस सेक्शन में उन विषयों के बारे में बताया गया है जिनके बारे में आपको गतिविधि के ट्रांज़िशन को सही तरीके से लागू करने के लिए जानना ज़रूरी है. इन विषयों में, एक ऐक्टिविटी से दूसरी ऐक्टिविटी शुरू करना, ऐक्टिविटी की स्थिति सेव करना, और ऐक्टिविटी की स्थिति वापस लाना शामिल है.
एक गतिविधि से दूसरी गतिविधि शुरू करना
किसी ऐक्टिविटी को अक्सर किसी समय दूसरी ऐक्टिविटी शुरू करने की ज़रूरत होती है. उदाहरण के लिए, ऐसा तब होता है, जब किसी ऐप्लिकेशन को मौजूदा स्क्रीन से नई स्क्रीन पर जाना होता है.
आपकी गतिविधि को नई गतिविधि से कोई नतीजा चाहिए या नहीं, इसके आधार पर नई गतिविधि शुरू करने के लिए, startActivity या startActivityForResult में से किसी एक तरीके का इस्तेमाल करें. दोनों ही मामलों में, आपको Intent ऑब्जेक्ट पास करना होगा.
Intent ऑब्जेक्ट से, उस गतिविधि के बारे में पता चलता है जिसे आपको शुरू करना है. इसके अलावा, इससे उस कार्रवाई के बारे में भी पता चलता है जिसे आपको पूरा करना है. सिस्टम आपके लिए सही गतिविधि चुनता है. यह किसी दूसरे ऐप्लिकेशन से भी हो सकती है. Intent ऑब्जेक्ट में, शुरू की गई ऐक्टिविटी के लिए इस्तेमाल किया जाने वाला कम डेटा भी हो सकता है. Intent क्लास के बारे में ज़्यादा जानने के लिए, इंटेंट और इंटेंट फ़िल्टर देखें.
startActivity
अगर नई गतिविधि को कोई नतीजा नहीं दिखाना है, तो मौजूदा गतिविधि startActivity तरीके को कॉल करके इसे शुरू कर सकती है.
अपने ऐप्लिकेशन में काम करते समय, आपको अक्सर किसी जानी-पहचानी गतिविधि को लॉन्च करने की ज़रूरत होती है. उदाहरण के लिए, यहां दिए गए कोड स्निपेट में, SignInActivity नाम की गतिविधि को लॉन्च करने का तरीका बताया गया है.
Kotlin
val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)
Java
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
आपका ऐप्लिकेशन, आपकी गतिविधि के डेटा का इस्तेमाल करके कुछ कार्रवाई भी कर सकता है. जैसे, ईमेल, टेक्स्ट मैसेज या स्टेटस अपडेट भेजना. इस मामले में, हो सकता है कि आपके ऐप्लिकेशन में ऐसी कार्रवाइयाँ करने के लिए अपनी गतिविधियाँ न हों. इसलिए, डिवाइस पर मौजूद अन्य ऐप्लिकेशन की ओर से उपलब्ध कराई गई गतिविधियों का इस्तेमाल किया जा सकता है. ये गतिविधियाँ, आपके लिए कार्रवाइयाँ कर सकती हैं.
यहां इंटेंट बहुत काम आते हैं. आपके पास ऐसा इंटेंट बनाने का विकल्प होता है जो आपकी पसंद के मुताबिक किसी कार्रवाई के बारे में बताता है. इसके बाद, सिस्टम किसी दूसरे ऐप्लिकेशन से सही ऐक्टिविटी लॉन्च करता है. अगर इंटेंट को हैंडल करने के लिए एक से ज़्यादा गतिविधियां उपलब्ध हैं, तो उपयोगकर्ता यह चुन सकता है कि उसे किस गतिविधि का इस्तेमाल करना है. उदाहरण के लिए, अगर आपको उपयोगकर्ता को ईमेल मैसेज भेजने की अनुमति देनी है, तो यह इंटेंट बनाया जा सकता है:
Kotlin
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)
Java
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
इंटेंट में जोड़ा गया EXTRA_EMAIL अतिरिक्त पैरामीटर, ईमेल पतों का एक स्ट्रिंग ऐरे होता है. इस ऐरे में मौजूद ईमेल पतों पर ईमेल भेजा जाता है. जब कोई ईमेल ऐप्लिकेशन इस इंटेंट का जवाब देता है, तो वह एक्स्ट्रा में दिए गए स्ट्रिंग ऐरे को पढ़ता है और पतों को ईमेल कंपोज़िशन फ़ॉर्म के "प्रति" फ़ील्ड में रखता है. इस स्थिति में, ईमेल ऐप्लिकेशन की गतिविधि शुरू हो जाती है. जब उपयोगकर्ता का काम पूरा हो जाता है, तब आपकी गतिविधि फिर से शुरू हो जाती है.
startActivityForResult
कभी-कभी, आपको किसी गतिविधि के खत्म होने पर उसका नतीजा वापस चाहिए होता है. उदाहरण के लिए, कोई ऐसी गतिविधि शुरू की जा सकती है जिससे उपयोगकर्ता, संपर्कों की सूची में से किसी व्यक्ति को चुन सके. यह फ़ंक्शन, चुने गए व्यक्ति को वापस भेजता है. ऐसा करने के लिए, startActivityForResult(Intent, int) तरीके का इस्तेमाल करें. इसमें पूर्णांक पैरामीटर, कॉल की पहचान करता है.
इस आइडेंटिफ़ायर का इस्तेमाल, एक ही गतिविधि से startActivityForResult(Intent, int) को किए गए कई कॉल के बीच अंतर करने के लिए किया जाता है. यह ग्लोबल आइडेंटिफ़ायर नहीं है. साथ ही, इससे अन्य ऐप्लिकेशन या गतिविधियों के साथ टकराव होने का खतरा नहीं होता. नतीजा, onActivityResult(int, int, Intent) तरीके से वापस आता है.
जब कोई चाइल्ड ऐक्टिविटी बंद होती है, तो वह setResult(int) को कॉल करके अपने पैरंट को डेटा भेज सकती है. बच्चे की गतिविधि को नतीजे का कोड देना होगा. यह स्टैंडर्ड नतीजे RESULT_CANCELED, RESULT_OK या RESULT_FIRST_USER से शुरू होने वाली कोई भी कस्टम वैल्यू हो सकती है.
इसके अलावा, बच्चे की गतिविधि से जुड़ा डेटा, Intent ऑब्जेक्ट के तौर पर भी दिखाया जा सकता है. इसमें वह अतिरिक्त डेटा शामिल होता है जो उसे चाहिए. पैरंट गतिविधि, जानकारी पाने के लिए onActivityResult(int, int, Intent) तरीके का इस्तेमाल करती है. साथ ही, पैरंट गतिविधि के लिए मूल रूप से दिए गए पूर्णांक आइडेंटिफ़ायर का इस्तेमाल करती है.
अगर किसी वजह से बच्चे की गतिविधि पूरी नहीं होती है, जैसे कि क्रैश हो जाना, तो अभिभावक की गतिविधि को RESULT_CANCELED कोड के साथ नतीजा मिलता है.
Kotlin
class MyActivity : Activity() {
// ...
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// When the user center presses, let them pick a contact.
startActivityForResult(
Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
PICK_CONTACT_REQUEST)
return true
}
return false
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
when (requestCode) {
PICK_CONTACT_REQUEST ->
if (resultCode == RESULT_OK) {
// A contact was picked. Display it to the user.
startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
}
}
}
companion object {
internal val PICK_CONTACT_REQUEST = 0
}
}
Java
public class MyActivity extends Activity {
// ...
static final int PICK_CONTACT_REQUEST = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// When the user center presses, let them pick a contact.
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// A contact was picked. Display it to the user.
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}
गतिविधियों को व्यवस्थित करना
जब कोई ऐक्टिविटी दूसरी ऐक्टिविटी शुरू करती है, तो दोनों के लाइफ़साइकल में बदलाव होता है. पहली गतिविधि काम करना बंद कर देती है और रुकी हुई या बंद स्थिति में चली जाती है. वहीं, दूसरी गतिविधि बनाई जाती है. अगर इन गतिविधियों में, डिस्क या किसी अन्य जगह पर सेव किया गया डेटा शेयर किया जाता है, तो यह समझना ज़रूरी है कि दूसरी गतिविधि बनाने से पहले, पहली गतिविधि पूरी तरह से बंद नहीं होती. इसके बजाय, दूसरे को शुरू करने की प्रोसेस, पहले को बंद करने की प्रोसेस के साथ ओवरलैप होती है.
लाइफ़साइकल कॉलबैक का क्रम अच्छी तरह से तय किया गया है. खास तौर पर, जब दो ऐक्टिविटी एक ही प्रोसेस में हों. दूसरे शब्दों में कहें, तो एक ही ऐप्लिकेशन में हों और एक ऐक्टिविटी दूसरी ऐक्टिविटी को शुरू कर रही हो. गतिविधि A से गतिविधि B शुरू होने पर, यहाँ दिए गए क्रम में कार्रवाइयाँ होती हैं:
- गतिविधि A का
onPauseतरीका लागू होता है. - गतिविधि B के
onCreate,onStart, औरonResumeतरीके क्रम से लागू होते हैं. अब ऐक्टिविटी B पर उपयोगकर्ता का फ़ोकस है. - अगर गतिविधि A अब स्क्रीन पर नहीं दिख रही है, तो इसका
onStopतरीका काम करेगा.
लाइफ़साइकल के कॉलबैक की इस सीक्वेंस से, एक गतिविधि से दूसरी गतिविधि में जानकारी के ट्रांज़िशन को मैनेज किया जा सकता है.