ফ্র্যাগমেন্ট লাইফসাইকেল

প্রতিটি Fragment ইনস্ট্যান্সের নিজস্ব লাইফসাইকেল আছে। ব্যবহারকারী আপনার অ্যাপে নেভিগেট ও ইন্টার‍্যাক্ট করলে, আপনার ফ্র্যাগমেন্টগুলি তাদের লাইফসাইকেলে বিভিন্ন স্টেটের মাধ্যমে ট্রানজিশন করে, কারণ সেগুলি স্ক্রিনে যোগ করা, সরানো এবং প্রবেশ বা প্রস্থান করা হয়।

লাইফসাইকেল ম্যানেজ করতে, Fragment LifecycleOwner প্রয়োগ করে, একটি Lifecycle অবজেক্ট এক্সপোজ করে যা আপনি getLifecycle() পদ্ধতির মাধ্যমে অ্যাক্সেস করতে পারবেন।

প্রতিটি সম্ভাব্য Lifecycle স্টেট Lifecycle.State enum-এ দেখানো হয়েছে।

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() কলব্যাক ইনভোক করা হয়।

ফ্র্যাগমেন্ট ও ভিউ আবার শুরু করা হয়েছে

ফ্র্যাগমেন্ট দেখা গেলে, সব Animator এবং Transition এফেক্ট শেষ হয়ে যায় এবং ফ্র্যাগমেন্ট ব্যবহারকারীর ইন্টার‍্যাকশনের জন্য রেডি হয়ে যায়। ফ্র্যাগমেন্টের Lifecycle RESUMED স্ট্যাটাসে চলে যায় এবং onResume() কলব্যাক চালু হয়।

RESUMED-এ ট্রানজিশন হল উপযুক্ত সিগন্যাল যা নির্দেশ করে যে ব্যবহারকারী এখন আপনার ফ্র্যাগমেন্টের সাথে ইন্টার‍্যাক্ট করতে পারবেন। যেসব ফ্র্যাগমেন্ট RESUMED নয়, সেগুলির ভিউতে ম্যানুয়ালি ফোকাস সেট করা বা ইনপুট পদ্ধতির দৃশ্যমানতা ম্যানেজ করার চেষ্টা করা উচিত নয়।

নিম্নমুখী অবস্থার পরিবর্তন

কোনও ফ্র্যাগমেন্ট নিচের দিকে কোনও নিম্নতর লাইফসাইকেল স্টেটে গেলে, প্রাসঙ্গিক Lifecycle.Event ফ্র্যাগমেন্টের ভিউ Lifecycle-এর মাধ্যমে অবজারভারদের কাছে এমিট করা হয়, যদি ইনস্ট্যান্টিয়েট করা হয়, তারপরে ফ্র্যাগমেন্টের Lifecycle। ফ্র্যাগমেন্টের লাইফসাইকেল ইভেন্ট এমিট হওয়ার পরে, ফ্র্যাগমেন্টটি সংশ্লিষ্ট লাইফসাইকেল কলব্যাককে কল করে।

ফ্র্যাগমেন্ট ও ভিউ শুরু হয়েছে

ব্যবহারকারী ফ্র্যাগমেন্ট থেকে বেরিয়ে আসতে শুরু করলে এবং ফ্র্যাগমেন্টটি তখনও দেখা গেলে, ফ্র্যাগমেন্ট ও তার ভিউয়ের জন্য Lifecycle STARTED স্টেটে ফিরে যায় এবং ON_PAUSE ইভেন্ট তার অবজারভারদের কাছে পাঠায়। ফ্র্যাগমেন্ট তখন তার onPause() কলব্যাককে ইনভোক করে।

ফ্র্যাগমেন্ট ও ভিউ তৈরি করা হয়েছে

ফ্র্যাগমেন্টটি আর দেখা না গেলে, ফ্র্যাগমেন্টের জন্য Lifecycle এবং এর ভিউ CREATED স্টেটে সরানো হয় এবং ON_STOP ইভেন্ট তাদের অবজারভারদের কাছে এমিট করে। এই স্টেট ট্রানজিশন শুধুমাত্র পেরেন্ট অ্যাক্টিভিটি বা ফ্র্যাগমেন্ট বন্ধ হওয়ার কারণে ট্রিগার হয় না, বরং পেরেন্ট অ্যাক্টিভিটি বা ফ্র্যাগমেন্টের মাধ্যমে স্টেট সেভ হওয়ার কারণেও ট্রিগার হয়। এই আচরণ গ্যারেন্টি দেয় যে ফ্র্যাগমেন্টের স্ট্যাটাস সেভ করার আগে ON_STOP ইভেন্টটি ইনভোক করা হয়েছে। এর ফলে ON_STOP ইভেন্টটি হল শেষ পয়েন্ট যেখানে FragmentManager-এর উপর FragmentTransaction করা নিরাপদ।

ছবি ২-এ যেমন দেখানো হয়েছে, API লেভেলের উপর ভিত্তি করে onStop() কলব্যাক এবং onSaveInstanceState()-এর মাধ্যমে স্ট্যাটাস সেভ করার ক্রম আলাদা হয়। API 28-এর আগের সব API লেভেলের জন্য, onStop()-এর আগে onSaveInstanceState() ইনভোক করা হয়। API লেভেল ২৮ এবং তার থেকে বেশি ভার্সনের ক্ষেত্রে, কলিং অর্ডার উল্টে যায়।

onStop() এবং onSaveInstanceState()-এর জন্য কলিং অর্ডারের পার্থক্য
ছবি ২. onStop() এবং onSaveInstanceState()-এর জন্য কলিং অর্ডারের পার্থক্য।

ফ্র্যাগমেন্ট তৈরি করা হয়েছে এবং ভিউ ধ্বংস করা হয়েছে

সব এক্সিট অ্যানিমেশন ও ট্রানজিশন সম্পূর্ণ হওয়ার পরে এবং ফ্র্যাগমেন্টের ভিউ উইন্ডো থেকে ডিটাচ করা হলে, ফ্র্যাগমেন্টের ভিউ Lifecycle DESTROYED স্ট্যাটাসে সরানো হয় এবং ON_DESTROY ইভেন্ট এর অবজারভারদের কাছে এমিট করে। ফ্র্যাগমেন্টটি তখন তার onDestroyView() কলব্যাককে আহ্বান করে। এই পর্যায়ে, ফ্র্যাগমেন্টের ভিউ তার লাইফসাইকেলের শেষে পৌঁছে গেছে এবং getViewLifecycleOwnerLiveData() null ভ্যালু রিটার্ন করে।

এই মুহূর্তে, ফ্র্যাগমেন্টের ভিউয়ের সব রেফারেন্স সরিয়ে দিতে হবে, যাতে ফ্র্যাগমেন্টের ভিউ গার্বেজ কালেক্ট করা যায়।

Fragment DESTROYED

ফ্র্যাগমেন্ট সরিয়ে দেওয়া হলে অথবা FragmentManager নষ্ট হয়ে গেলে, ফ্র্যাগমেন্টের Lifecycle, DESTROYED স্ট্যাটাসে চলে যায় এবং এর পর্যবেক্ষকদের ON_DESTROY ইভেন্ট পাঠায়। ফ্র্যাগমেন্টটি তখন তার onDestroy() কলব্যাককে আহ্বান করে। এই পর্যায়ে, ফ্র্যাগমেন্টটি তার লাইফসাইকেলের শেষে পৌঁছে গেছে।

অতিরিক্ত রিসোর্স

ফ্র্যাগমেন্ট লাইফসাইকেল সম্পর্কে আরও তথ্য পেতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।

নির্দেশিকা

ব্লগ