फ़्रैगमेंट लाइफ़साइकल

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

लाइफ़साइकल मैनेज करने के लिए, Fragment LifecycleOwner को लागू करता है. इससे, Lifecycle ऑब्जेक्ट दिखता है, जिसे getLifecycle() तरीके से ऐक्सेस किया जा सकता है.

Lifecycle की हर संभावित स्थिति, Lifecycle.State एनम में दिखाई जाती है.

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

LifecycleObserver का इस्तेमाल करने के विकल्प के तौर पर, Fragment क्लास में कॉलबैक मैथड शामिल होते हैं. ये मैथड, फ़्रैगमेंट के लाइफ़साइकल में होने वाले हर बदलाव से जुड़े होते हैं. इनमें ये शामिल हैं onCreate(), onStart(), onResume(), onPause(), onStop(), और onDestroy().

फ़्रैगमेंट के व्यू में एक अलग Lifecycle होता है, जिसे फ़्रैगमेंट के Lifecycle से अलग मैनेज किया जाता है. फ़्रैगमेंट अपने व्यू के लिए एक LifecycleOwner बनाए रखते हैं. इसे getViewLifecycleOwner() या getViewLifecycleOwnerLiveData() का इस्तेमाल करके ऐक्सेस किया जा सकता है. व्यू के Lifecycle का ऐक्सेस होना उन स्थितियों में मददगार होता है जहां लाइफ़साइकल के बारे में जानकारी रखने वाले कॉम्पोनेंट को सिर्फ़ तब काम करना चाहिए, जब फ़्रैगमेंट का व्यू मौजूद हो. जैसे, LiveData को सिर्फ़ स्क्रीन पर दिखाने के लिए निगरानी करना.

इस विषय में Fragment लाइफ़साइकल के बारे में पूरी जानकारी दी गई है. साथ ही, फ़्रैगमेंट के लाइफ़साइकल स्टेटस तय करने वाले कुछ नियमों के बारे में बताया गया है. साथ ही, Lifecycle स्टेटस और फ़्रैगमेंट लाइफ़साइकल कॉलबैक के बीच के संबंध को दिखाया गया है.

फ़्रैगमेंट और फ़्रैगमेंट मैनेजर

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

फ़्रैगमेंट के लाइफ़साइकल के अलावा, FragmentManager को फ़्रैगमेंट को अपनी होस्ट ऐक्टिविटी से जोड़ने और फ़्रैगमेंट के इस्तेमाल में न होने पर उन्हें अलग करने की ज़िम्मेदारी भी होती है. Fragment क्लास में दो कॉलबैक तरीक़े, onAttach() और onDetach() होते हैं. इनमें से किसी भी इवेंट के होने पर, काम करने के लिए इन्हें बदला जा सकता है.

onAttach() कॉलबैक तब ट्रिगर होता है, जब फ़्रैगमेंट को किसी FragmentManager में जोड़ा गया हो और उसे उसकी होस्ट ऐक्टिविटी से अटैच किया गया हो. इस समय, फ़्रैगमेंट चालू है और FragmentManager उसकी लाइफ़साइकल की स्थिति मैनेज कर रहा है. इस समय, FragmentManager के तरीके, जैसे कि findFragmentById(), यह फ़्रैगमेंट दिखाते हैं.

लाइफ़साइकल की स्थिति में बदलाव होने से पहले, onAttach() को हमेशा कॉल किया जाता है.

onDetach() कॉलबैक तब ट्रिगर होता है, जब फ़्रैगमेंट को FragmentManager से हटा दिया गया हो और उसे होस्ट गतिविधि से अलग कर दिया गया हो. फ़्रैगमेंट अब चालू नहीं है और findFragmentById() का इस्तेमाल करके, इसे वापस नहीं लाया जा सकता.

लाइफ़साइकल की स्थिति में बदलाव होने के बाद, onDetach() को हमेशा कॉल किया जाता है.

ध्यान दें कि ये कॉलबैक, FragmentTransaction, attach(), और detach() तरीकों से जुड़े नहीं हैं. इन तरीकों के बारे में ज़्यादा जानने के लिए, लेन-देन को फ़्रैगमेंट में बांटना लेख पढ़ें.

फ़्रैगमेंट लाइफ़साइकल की स्थितियां और कॉलबैक

किसी फ़्रैगमेंट के लाइफ़साइकल की स्थिति तय करते समय, FragmentManager इन बातों का ध्यान रखता है:

  • किसी फ़्रैगमेंट की ज़्यादा से ज़्यादा स्थिति, उसके FragmentManager से तय होती है. कोई फ़्रैगमेंट, FragmentManager की स्थिति से आगे नहीं बढ़ सकता.
  • FragmentTransaction के हिस्से के तौर पर, setMaxLifecycle() का इस्तेमाल करके, किसी फ़्रैगमेंट पर लाइफ़साइकल की ज़्यादा से ज़्यादा स्थिति सेट की जा सकती है .
  • किसी फ़्रैगमेंट का लाइफ़साइकल स्टेटस, उसके पैरंट से ज़्यादा नहीं हो सकता. उदाहरण के लिए, पैरंट फ़्रैगमेंट या गतिविधि को उसके चाइल्ड फ़्रैगमेंट से पहले शुरू किया जाना चाहिए. इसी तरह, चाइल्ड फ़्रैगमेंट को उनके पैरंट फ़्रैगमेंट या गतिविधि से पहले रोकना होगा.
फ़्रैगमेंट लाइफ़साइकल की स्थितियां और उनका फ़्रैगमेंट के लाइफ़साइकल कॉलबैक और फ़्रैगमेंट के व्यू लाइफ़साइकल, दोनों से संबंध
पहली इमेज. फ़्रैगमेंट Lifecycle की स्थितियां और उनका फ़्रैगमेंट के लाइफ़साइकल कॉलबैक और फ़्रैगमेंट के व्यू Lifecycle, दोनों से संबंध.

पहली इमेज में, फ़्रैगमेंट की हर Lifecycle स्थिति दिखाई गई है. साथ ही, यह भी बताया गया है कि ये स्थितियां, फ़्रैगमेंट के लाइफ़साइकल कॉलबैक और फ़्रैगमेंट के व्यू Lifecycle, दोनों से कैसे जुड़ी हैं.

फ़्रैगमेंट के लाइफ़साइकल के दौरान, वह अपनी स्थितियों में ऊपर और नीचे की ओर बढ़ता है. उदाहरण के लिए, बैक स्टैक में सबसे ऊपर जोड़ा गया फ़्रैगमेंट, CREATED से STARTED और फिर RESUMED पर ऊपर की ओर बढ़ता है. इसके उलट, जब कोई फ़्रैगमेंट बैक स्टैक से हटाया जाता है, तो वह इन स्थितियों से नीचे की ओर बढ़ता है. जैसे, RESUMED से STARTED से CREATED और आखिर में DESTROYED.

स्टेटस में होने वाले बदलाव

लाइफ़साइकल की स्थितियों में ऊपर की ओर बढ़ते समय, फ़्रैगमेंट सबसे पहले अपनी नई स्थिति के लिए, लाइफ़साइकल से जुड़े कॉलबैक को कॉल करता है. यह कॉलबैक पूरा होने के बाद, फ़्रैगमेंट के Lifecycle की मदद से, ऑब्ज़र्वर को काम का Lifecycle.Event भेजा जाता है. इसके बाद, अगर फ़्रैगमेंट का व्यू Lifecycle इंस्टैंशिएट किया गया है, तो उसे भी भेजा जाता है.

फ़्रैगमेंट बनाया गया

जब आपका फ़्रैगमेंट CREATED स्टेटस पर पहुंच जाता है, तो उसे FragmentManager में जोड़ दिया जाता है और onAttach() वाला तरीका पहले ही कॉल कर दिया जाता है.

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

यह ट्रांज़िशन, onCreate() कॉलबैक को ट्रिगर करता है. कॉलबैक को savedInstanceState Bundle आर्ग्युमेंट भी मिलता है. इसमें वह स्टेटस होता है जिसे पहले onSaveInstanceState() से सेव किया गया था. ध्यान दें कि फ़्रैगमेंट बनाने के बाद, savedInstanceState की वैल्यू null होती है. हालांकि, इसे फिर से बनाने पर, इसकी वैल्यू हमेशा शून्य से ज़्यादा होती है. भले ही, आपने onSaveInstanceState() को बदला न हो. ज़्यादा जानकारी के लिए, फ़्रैगमेंट की मदद से स्टेटस सेव करना देखें.

फ़्रैगमेंट बनाया गया और व्यू को शुरू किया गया

फ़्रैगमेंट का व्यू Lifecycle सिर्फ़ तब बनाया जाता है, जब आपका Fragment मान्य View इंस्टेंस उपलब्ध कराता है. ज़्यादातर मामलों में, @LayoutId का इस्तेमाल करने वाले फ़्रैगमेंट कन्स्ट्रक्टर का इस्तेमाल किया जा सकता है. इससे, सही समय पर व्यू अपने-आप बड़ा हो जाता है. प्रोग्राम के हिसाब से अपने फ़्रैगमेंट के व्यू को बड़ा करने या बनाने के लिए, onCreateView() को बदला भी जा सकता है.

अगर आपके फ़्रैगमेंट के व्यू को नॉन-नल View के साथ इंस्टैंशिएट किया जाता है, तो View को फ़्रैगमेंट पर सेट किया जाता है और getView() का इस्तेमाल करके उसे वापस पाया जा सकता है. इसके बाद, getViewLifecycleOwnerLiveData() को फ़्रैगमेंट के व्यू से जुड़े नए INITIALIZED LifecycleOwner से अपडेट किया जाता है. इस समय, onViewCreated() लाइफ़साइकल कॉलबैक भी ट्रिगर होता है.

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

फ़्रैगमेंट और व्यू बनाए गए

फ़्रैगमेंट का व्यू बनने के बाद, व्यू की पिछली स्थिति (अगर कोई हो) को वापस लाया जाता है. इसके बाद, व्यू के Lifecycle को CREATED स्थिति में ले जाया जाता है. व्यू के लाइफ़साइकल के मालिक, अपने ऑब्ज़र्वर को ON_CREATE इवेंट भी भेजते हैं. यहां आपको फ़्रैगमेंट के व्यू से जुड़ी किसी भी अतिरिक्त स्थिति को पहले जैसा करना चाहिए.

यह ट्रांज़िशन, onViewStateRestored() कॉलबैक को भी ट्रिगर करता है.

फ़्रैगमेंट और व्यू शुरू हो गया

हमारा सुझाव है कि लाइफ़साइकल के बारे में जानकारी देने वाले कॉम्पोनेंट को फ़्रैगमेंट की STARTED स्थिति से जोड़ा जाए. इससे यह पक्का होता है कि अगर फ़्रैगमेंट बनाया गया है, तो उसका व्यू उपलब्ध है. साथ ही, फ़्रैगमेंट के चाइल्ड FragmentManager पर FragmentTransaction करने के लिए सुरक्षित है. अगर फ़्रैगमेंट का व्यू नॉन-नल है, तो फ़्रैगमेंट के Lifecycle को STARTED पर ले जाने के तुरंत बाद, फ़्रैगमेंट का व्यू Lifecycle को STARTED पर ले जाया जाता है.

जब फ़्रैगमेंट STARTED हो जाता है, तो onStart() कॉलबैक को शुरू किया जाता है.

STARTED

फ़्रैगमेंट और व्यू फिर से शुरू किया गया

फ़्रैगमेंट दिखने पर, सभी Animator और Transition इफ़ेक्ट लागू हो जाते हैं. साथ ही, फ़्रैगमेंट उपयोगकर्ता के इंटरैक्शन के लिए तैयार हो जाता है. फ़्रैगमेंट का Lifecycle, RESUMED स्टेटस पर चला जाता है और onResume() कॉलबैक को शुरू किया जाता है.

RESUMED पर ट्रांज़िशन, यह बताने के लिए सही सिग्नल है कि उपयोगकर्ता अब आपके फ़्रैगमेंट से इंटरैक्ट कर सकता है. RESUMED नहीं

स्टेट में नीचे की ओर होने वाले बदलाव

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

फ़्रैगमेंट और व्यू शुरू हो गया

जब उपयोगकर्ता फ़्रैगमेंट से बाहर निकलने लगता है और फ़्रैगमेंट अब भी दिख रहा होता है, तब फ़्रैगमेंट और उसके व्यू के लिए Lifecycle को STARTED स्थिति में वापस ले जाया जाता है. साथ ही, अपने ऑब्ज़र्वर को ON_PAUSE इवेंट भेजा जाता है. इसके बाद, फ़्रैगमेंट अपने onPause() कॉलबैक को ट्रिगर करता है.

फ़्रैगमेंट और व्यू बनाए गए

फ़्रैगमेंट के दिखने बंद होने के बाद, फ़्रैगमेंट और उसके व्यू के लिए Lifecycle को CREATED स्थिति में ले जाया जाता है. साथ ही, उनके ऑब्जर्वर को ON_STOP इवेंट भेजा जाता है. यह स्टेटस ट्रांज़िशन, सिर्फ़ पेरंट ऐक्टिविटी या फ़्रैगमेंट के बंद होने से ही नहीं, बल्कि पेरंट ऐक्टिविटी या फ़्रैगमेंट के स्टेटस सेव होने से भी ट्रिगर होता है. इस व्यवहार से यह पक्का होता है कि ON_STOP इवेंट, फ़्रैगमेंट की स्थिति सेव होने से पहले ट्रिगर हो. इससे ON_STOP इवेंट, चाइल्ड FragmentManager पर FragmentTransaction करने के लिए आखिरी पॉइंट बन जाता है.

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

onStop() और onSaveInstanceState() के लिए कॉल करने के क्रम में अंतर
दूसरी इमेज. onStop() और onSaveInstanceState() के लिए कॉल करने के क्रम में अंतर.

फ़्रैगमेंट बनाया गया और व्यू मिटा दिया गया

विंडो से बाहर निकलने के सभी ऐनिमेशन और ट्रांज़िशन पूरे होने और फ़्रैगमेंट के व्यू को विंडो से अलग करने के बाद, फ़्रैगमेंट के व्यू Lifecycle को DESTROYED स्टेटस में ले जाया जाता है. साथ ही, यह अपने ऑब्जर्वर को ON_DESTROY इवेंट भेजता है. इसके बाद, फ़्रैगमेंट अपने onDestroyView() कॉलबैक को शुरू करता है. इस समय, फ़्रैगमेंट का व्यू अपने लाइफ़साइकल के आखिर में पहुंच जाता है और getViewLifecycleOwnerLiveData() null वैल्यू दिखाता है.

इस समय, फ़्रैगमेंट के व्यू के सभी रेफ़रंस हटा दिए जाने चाहिए, ताकि फ़्रैगमेंट के व्यू को गै़रबेज कलेक्शन किया जा सके.

फ़्रैगमेंट को मिटा दिया गया

अगर फ़्रैगमेंट को हटाया जाता है या FragmentManager को नष्ट कर दिया जाता है, तो फ़्रैगमेंट का Lifecycle, DESTROYED स्थिति में चला जाता है और अपने ऑब्ज़र्वर को ON_DESTROY इवेंट भेजता है. इसके बाद, फ़्रैगमेंट अपने onDestroy() कॉलबैक को शुरू करता है. इस समय, फ़्रैगमेंट का लाइफ़साइकल खत्म हो जाता है.

अन्य संसाधन

फ़्रैगमेंट के लाइफ़साइकल के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य रिसॉर्स देखें.

गाइड

ब्लॉग