পোস্টটি পড়া হয়েছে 5,391 বার
Android activity lifecycle in Bengali

Android Activity Lifecycle

Post updated on 17th January, 2020 at 10:01 am

এক বা একাধিক Activity এর সমন্বয়ে গঠিত হয় একেকটা অ্যান্ড্রয়েড অ্যাপ। সাধারণত একাধিক অ্যাক্টিভিটি নিয়েই আমাদের কাজ করতে হয়। একটা অ্যাক্টিভিটি তৈরি হওয়া থেকে শুরু করে সেটা destroy হওয়া পর্যন্ত অনেকগুলো ধাপ রয়েছে। শুরু থেকে শেষ পর্যন্ত সবগুলো ধাপকে আমরা বলে থাকি অ্যাক্টিভিটি লাইফসাইকেল। এই লাইফসাইকেলের বিভিন্ন স্টেজে আমাদের নানারকম কাজকর্ম করার দরকার হতে পারে। এজন্য জানা দরকার অ্যাক্টিভিটিটি এখন লাইফসাইকেলের কোন স্টেজে রয়েছে। তো এই লাইফসাইকেলের প্রতিটি স্টেজে কী ঘটে আর সে অনুযায়ী আমাদের কী কী স্টেপ নেয়া দরকার হতে পারে সে বিষয়েই আজকের এই লেখা।

Prerequisites for understanding this post

এই পোস্টটি পড়ে উপকৃত হবার জন্য অ্যান্ড্রয়েড অ্যাপ ডেভেলপমেন্টে অন্তত কিছুদিন কাজ করার অভিজ্ঞতা থাকলে সুবিধা হবে।  আপনাকে জানতে অ্যাক্টিভিটি কী? কিভাবে একটা বাটন ক্লিক কাজ করে? কিভাবে একটা অ্যাক্টিভিটি থেকে আরেকটা অ্যাক্টিভিটিকে স্টার্ট করা যায়। কিভাবে একটা অ্যাক্টিভিটিকে বন্ধ করে দিতে হয়? এই ধরনের ছোটখাটো কাজের আইডিয়া থাকলেই আপনার এই পোস্ট বুঝতে কোনো সমস্যা হবে না।

আপনি যদি অ্যান্ড্রয়েডে একদম নতুন হয়ে থাকেন, এখন পর্যন্ত “Hello World” টাইপের কোনো অ্যাপও নিজে নিজে বানিয়ে run করে দেখা হয়ে ওঠে নি। তাহলে এই পোস্টটি পড়লে হয়ত খুব একটা লাভ নাও হতে পারে। সেক্ষেত্রে  অ্যান্ড্রয়েড অ্যাপ ডেভেলপমেন্ট শেখার একটা গাইডলাইন পেতে পারেন এখান থেকে

Concept of Lifecycle

Lifecycle বুঝার আগে lifetime-টা বুঝা দরকার। কনসেপ্টটা সোজাসাপ্টা। এর কোনো টেকনিক্যাল ভিত্তি আছে কিনা জানা নাই। মনে হচ্ছে এটা নিয়ে উদাহরণ দিলে নতুন ডেভেলপারদের বুঝতে খানিকটা সুবিধা হবে।

অ্যাক্টিভিটির লাইফটাইম বুঝার আগে মানুষের জীবনের লাইফটাইমের দিকে নজর দেয়া যাক। আমাদের লাইফটাইম বা জীবদ্দশা বলতে কী বুঝি? জন্ম থেকে মৃত্যু পর্যন্ত এই সময়টাকেই আমরা জীবদ্দশা বা লাইফটাইম বলে থাকি। এই লাইফটাইম কি পুরোটা একই রকম নাকি কিছু পর্যায় দিয়ে ভাগ করা যায়? শৈশব, কৈশর, যৌবন, বৃদ্ধকাল ইত্যাদি ভাগে ভাগ করতে পারি। প্রতিটা ভাগের কিছু করণীয়-বর্জনীয় ব্যাপার-স্যাপার আছে। আবার স্কুল লাইফ, কলেজ লাইফ, ভার্সিটি লাইফ, জব লাইফ ইত্যাদি দিয়েও ভাগ করা যায়।

প্রাতিষ্ঠানিক শিক্ষার ভিত্তিতে ভাগ না করে আমরা বরং বয়সের ভিত্তিতে ভাগ করি। একটা মানুষের জন্ম থেকে চিন্তা করা যাক। নাহ! জন্ম না… তার দেহে প্রাণ সঞ্চার থেকে শুরু করি। গর্ভবতী মায়ের গর্ভধারণের চতুর্থ মাস থেকে তার গর্ভস্থ সন্তানের কিডনি সচল হয়। তখন বাচ্চা ঢোক গিলতে পারে ও শুনতে পারে। পঞ্চম মাসে সে সক্রিয় হয়ে ওঠে। মা তার নড়াচড়া বুঝতে পারেন। এ সময় বাচ্চাটি ঘুমায় ও জেগে ওঠে। এটা প্রতিটা মানুষের জীবনের একটা নির্দিষ্ট স্টেজ। এরপর আস্তে আস্তে শিশুর অন্যান্য অঙ্গ-প্রত্যঙ্গ কাজ করতে শুরু করে। এই সব কিছুই কিন্তু ঘটছে একটা পূর্ণাঙ্গ শিশুর জন্ম দেয়ার জন্য, যাকে এখনো কেউ চর্মচক্ষু দিয়ে দেখেই নি। আমরা বলতে পারি মানুষ হিসেবে জন্ম নেয়ার পূর্বের স্টেজ এটা। এই স্টেজে শিশুর প্রয়োজনীয় সব অর্গান বা ফাংশনালিটি রেডি করা হয়। সব ঠিকঠাক থাকলে এরপর সময় মত শিশুর জন্ম হয়। এরপর একটা বিরাট সময় অতিবাহিত হয় জন্ম নেয়া শিশুটিকে মানুষের মত মানুষ হিসাবে গড়ে তোলার প্রচেষ্টায়। তাকে পোশাক পড়ানো হয়, খাবার খাওয়ানো হয়, কথা বলা শেখানো হয়, প্রাতিষ্ঠানিক শিক্ষা দেয়া হয়, কাজকর্ম করতে শেখানো হয় ইত্যাদি। এরপর সব স্বাভাবিক থাকলে একটা সময় শৈশব, কৈশর, যৌবন পার হয়ে মানুষ বৃদ্ধ হয়। নানারকম অসুখ-বিসুখে মানুষ তখন কাবু হতে থাকে। হয়ত কোনো এক সময় অচেতন অবস্থায় তাকে মেডিকেলে ভর্তি করানো হয়। আইসিইউতে থাকাকালীন অবস্থায় ডাক্তার হয়ত রুগিকে “ক্লিনিক্যাল্যি ডেড” ঘোষণা করেন। অর্থাৎ মারা যাবার কাছাকাছি কিন্তু এখনো মৃত না। সেই অবস্থা থেকে রুগি আবার ফিরে আসতে পারেন অথবা তার মৃত্যু হতে পারে। মৃত্যুর পর মুহূর্তেই সে ভ্যানিশ হয়ে যায় না। বরং কিছু আনুষ্ঠানিকতার মাধ্যমে তাকে কবরস্থ করা হয়। আপাতদৃষ্টিতে কবর দেয়ার পরেই মানুষটি আমাদের চোখের আড়াল হলো দৃষ্টির বাইরে চলে গেল। তখন কিন্তু স্বাভাবিক ভাবেই দুনিয়ার কোনো কিছুর সাথেই তার (লাশের) আর কোনো লেনদেন বা ডিপেন্ডেন্সি থাকে না। তিনি তখন এক অন্য ভুবনের বাসিন্দা। কিন্তু দাফনের আগ পর্যন্ত কিন্তু খানিকটা ডিপেন্ডেন্সি ছিল। তার পরিবারের মানুষেরা তাকে এক নজর দেখতে আসতে পারেন, তার নামাজে জানাজা পড়তে পারেন, তাকে খাটিয়ায় করে নিয়ে গিয়ে কবরস্থানে যেতে পারেন। এই স্টেজটা কিন্তু মারা যাবার পর, কিন্তু আমাদের লোকচক্ষুর আড়ালে যাবার আগে।

উপরের এই কথাগুলো খুবই কমন। এই পর্যায়গুলো এবার চোখ বন্ধ করে একটার পর একটা পয়েন্ট আকারে কল্পনা করা যাক। আমার ধারণা আপনি এই টাইপের একটা লিস্ট তৈরি করতে পারবেনঃ

  1. মানুষের (ভ্রুণ) সৃষ্টি। যা এখনো visible নয়
  2. মানুষের জন্ম। কিন্তু এখনো সে দুনিয়ায় একা চলতে পারে না। তাকে রেডি করতে হবে
  3. প্রাপ্ত বয়স্ক মানুষ। যে কিনা কাজকর্ম করতে পারে। ডাকলে সাড়া দেয় বা রিঅ্যাক্ট করে
  4. অসুস্থ্য হয়ে হাসপাতালে ভর্তি। হাসপাতালের বেড, ব্যালকনি ছাড়া বাইরের দুনিয়ায় তাকে দেখা যাচ্ছে না
  5. কোমায় আছে বা ক্লিনিক্যাল্যি ডেড। বাঁচার আশা নাই। (বিশেষ কয়েকজন ছাড়া) কেউ তাকে দেখতে পাচ্ছে না। বেঁচে উঠলে 6 নাম্বার পয়েন্টে যাবে। অন্যথায় 7 এ যাবে।
  6. কোমা থেকে সে ফিরে এসেছে। এ যেন তার নতুন জন্ম! 2 নাম্বার পয়েন্ট থেকে যেন সে আবার পথ চলতে শুরু করেছে। ছোট বেলার মত তাকে কিছুদিন ধরে ধরে সব কিছুতে সাহায্য করতে হচ্ছে
  7. যদি সে 5 নাম্বার পয়েন্ট থেকে 6 এ না যেত? অর্থাৎ সে ফিরে আসলো না। তাহলে ধরে নিতে হবে 5 নাম্বার স্টেজেই তার মৃত্যু হয়েছে। কিন্তু তখনো তাকে দেখা যাচ্ছিল। এটা দাফন স্টেজ। দাফন হয়েছে, তাই আর তাকে আমরা কেউই দেখতে পাচ্ছি না।

উপরের পয়েন্টগুলো হয়ত আপনার সাথে আমার ২-১ টায় ব্যতিক্রম ঘটতে পারে। কিন্তু মূল থিমটা একই থাকবে।

জানি না এই চিরচেনা একঘেয়ে কথাগুলো বলে পাঠকের ধৈর্য্যচ্যুতি করলাম কিনা। টেকনিক্যাল বিষয়ের ব্লগ পড়তে এসে মানুষের জন্ম-মৃত্যুর মত সেন্সিটিভ আর সবচেয়ে ধ্রুব সত্য নিয়ে কথা বলছি দেখে বিরক্ত হয়ে থাকতে পারেন। তবে বিরক্ত হলেও আমি মোটেই দুঃখিত নই। কারণ আমি জানি, আমি এগুলো কেন লিখছি।

এবার উপরের সাতটা পয়েন্টের মানুষ বা রুগির জায়গাগুলো “Activity” দিয়ে পাল্টে ফেলুন। তাহলে আপনি নিচের মত একটা লিস্ট পাবেনঃ

  1. অ্যাকটিভিটির সৃষ্টি। যা এখনো visible নয় (Created State)
  2. অ্যাক্টিভিটি তৈরি হয়ে আমাদের অ্যাপে ভিজিবল হয়েছে (Started State)
  3. অ্যাক্টিভিটির সাথে ইন্টার‍্যাকশন করা যাচ্ছে। ক্লিক করলে কোনো অ্যাকশন হয় বা রিঅ্যাক্ট করে (Resumed State)
  4. অ্যাক্টিভিটির উপর আরেকটা অ্যাক্টিভিটি চলে আসছে। মানে আগেরটাকে ঢেকে দিতে চাচ্ছে (Paused State)
  5. অ্যাক্টিভিটি আর দেখা যাচ্ছে না। অন্য অ্যাপ বা অ্যাক্টিভিটি তাকে পুরোপুরে ঢেকে দিয়েছে। যদি ইউজার আবার এই অ্যাক্টিভিটিতে ফিরে আসে তাহলে 6 নাম্বার পয়েন্টে যাবে। অন্যথায় 7 এ যাবে (Stopped State)
  6. অ্যাপ ইউজার আবার আগের অ্যাক্টিভিটিতে নেভিগেট করলো। ফলে সেটা আবার অ্যাপে ভিজিবল হতে যাচ্ছে (Restarted State)
  7. অ্যাক্টিভিটিটি এখন আর নাই। Destroy বা শেষ হয়ে গিয়েছে (Destroyed State)

একটা অ্যাক্টিভিটিতে আসলে এই স্টেজগুলোই থাকে। অ্যাক্টিভিটির শুরু থেকে নিয়ে শেষ হওয়া পর্যন্ত সে এই সবগুলো স্টেজের মধ্য দিয়েই পার হয়। এগুলোই Android Activity Lifecycle নামে পরিচিত। আমি 6 নাম্বার পয়েন্টটাকে আলাদা স্টেট হিসাবে উল্লেখ করেছি। কিন্তু গুগলের অফিসিয়াল ডকে Restarted State বলে কোনো স্টেটের উল্লেখ নাই। লাইফসাইকেলের ফ্লো চার্টে onRestart() মেথডের উল্লেখ রয়েছে। তাই Restarted State টা জাস্ট বুঝার জন্য মাথায় রাখতে পারেন। কোনো ইন্টারভিউতে লাইফসাইকেলের সংখ্যা জিজ্ঞাসা করা হলে বলবেন ৬ টি।

Details of Android Activity Lifecycle

কোনো একটা অ্যাক্টিভিটি যখন ভিজিবল হয় এরপর আমরা সেই অ্যাক্টিভিটির সাথে ইন্টারঅ্যাক্ট করতে পারি। এরপর কোনো interruption আসলে বা ইউজার অন্য অ্যাক্টিভিটিতে গেলে আগের অ্যাক্টিভিটির স্টেট চেঞ্জ হয়। একটা অ্যাক্টিভিটি কোন কোন স্টেটে থাকতে পারে সেগুলোই লাইফসাইকেলের মধ্যে আলোচনা করা হয়।

পোস্টের শুরুতে উদাহরণ দিয়ে মূল কথাগুলো বুঝানোর চেষ্টা করা হয়েছে। এখন একটু টেকনিক্যাল আলোচনা করা যাক কেতাবী ভাষায়। অ্যান্ড্রয়েড অ্যাপের অ্যাক্টিভিটি লাইফসাইকেলের প্রতিটা স্টেজের জন্য নির্দিষ্ট CallBack method রয়েছে। অর্থাৎ এই কলব্যাক মেথডগুলো override করলেই আমরা অ্যাক্টিভিটির সবকটি স্টেজ detect করতে পারবো। আর লাইফসাইকেলের স্টেজগুলোকে আমরা এর কলব্যাক মেথডের নামেই নামকরণ করে থাকি। নিচে কলব্যাক মেথডগুলোর বিস্তারিত আলোচনা করা হলো। উপরে থাকা লিস্ট আর নিচের আলোচনাটুকু মাথায় রেখে Activity Lifecycle এর এই ছবিটা দেখলে আশা করি বুঝতে সুবিধা হবে।

Android Activity Lifecycle. Collected from Official Doc

onCreate (Created State)

একটা অ্যাক্টিভিটি launch করার পর সর্বপ্রথম এই স্টেজে সে থাকে। এই স্টেজের মাধ্যমেই অ্যাক্টিভিটির শুরু। তাই অন্যান্য স্টেজের মেথডগুলো কল করা হোক বা না হোক এই onCreate() মেথডটি সব অ্যাক্টিভিটির ক্ষেত্রেই কল করতে হয়। Activity’র কাজ শুরুর জন্য যত ধরনের initialization বা view binding এগুলো সব এই স্টেটেই করা হয়ে থাকে। উদাহরণ হিসাবে বলা যেতে পারেঃ আমরা এই স্টেটের ভিতরই setContentView() method call করে দেখিয়ে দেই যে কোন layout এর xml ফাইলটা আমরা এখন ভিউতে দেখাতে চাই। TextView, EditText ইত্যাদি widget এর initialization এর কাজও আমরা এই স্টেটে করে থাকি findViewById() মেথড কল করার মাধ্যমে। এছাড়াও প্রয়োজনীয় লজিক্যাল অপারেশন, ব্যাকগ্রাউন্ড থ্রেড বা ভ্যারিয়েবল ইনিশিয়ালাইজেশনের কাজগুলোও এই স্টেটে হয়ে থাকে। সহজ কথায় বললেঃ অ্যাক্টিভিটির মূল কাজকর্ম যা আছে তা সব onCreate() মেথডের ভিতরই করা হয়ে থাকে।

এত কিছু এখানে করা হলো, কিন্তু খেয়াল করার বিষয় হচ্ছে এখনো কিন্তু আমাদের অ্যাক্টিভিটি স্ক্রিনে ভিজিবল নয়। তার মানে একটা অ্যাক্টিভিটিকে ওপেন করার জন্য কমান্ড দেয়ার পর যেই এক সেকেন্ড সময়ের মত লাগে এই সময়ের মধ্যে এত এত কাজ হয়। যখন onCreate() মেথডের execution শেষ হয় তখন অ্যাক্টিভিটি Created State থেকে Started State এ প্রবেশ করে। আর অ্যান্ড্রয়েড অপারেটিং সিসটেম তখন onStart() মেথড কল করে।

onStart

Activity যখন Started State এ প্রবেশ করে, সিসটেম তখন onStart() মেথড কল করে। এই স্টেটে এসেই অ্যাক্টিভিটিটি স্ক্রিনে ভিজিবল হয়। কিন্তু তখনও অ্যাক্টিভিটিটি ইউজারের সাথে interaction করার উপযোগি হয়ে ওঠে না। এই স্টেটে খুব বেশি একটা কোড এক্সিকিউট করা হয় না। কারণ অ্যাক্টিভিটি এই স্টেট থেকে বেশ দ্রুতই পরের স্টেটে চলে যায়। onStart() মেথডের ভিতর সাধারণত BroadCastReceiver বা কোনো ইভেন্টের জন্য রেজিস্টার করার কোড লিখা হয়ে থাকে যেগুলোর সাথে UI এর সম্পর্ক রয়েছে। যেমন EventBus Library এর কোনো ইভেন্টের জন্য রেজিস্টার করতে হয় এই স্টেটে (EventBus সম্পর্কে আলাদা ব্লগ পোস্ট পড়তে ক্লিক করুন)। এই স্টেট থেকে বের হয়ে Resumed State এ প্রবেশ করে। সিসটেম তখন onResume মেথড কল করে।

onResume

অ্যাক্টিভিটি যখন foreground এ এবং তা ইউজারের বিভিন্ন ইভেন্টের উপর (যেমনঃ বাটন ক্লিক, swipe, pull to refresh etc) রেসপন্স করতে সক্ষম তখন onResume() মেথড কল হয়। ইউজার যতক্ষণ এই অ্যাক্টিভিটি দেখতে পাচ্ছে বা যতক্ষণ এটি ফোকাসে থাকছে ততক্ষণ এটা Resumed State-এই থাকে।

অ্যাপের বিভিন্ন ফিচারের প্রয়োজনে অনেক সময় অনেক ধরণের component আমাদের অ্যাপে ইউজ করতে হয়। যেগুলো ইউজ করা বেশ expensive. যেমন ক্যামেরা। এসব কম্পোনেন্ট আমরা সাধারণত Paused State এ গেলে release করে দেই। তা না হলে এগুলো অনেক অনেক মেমরি, ব্যাটারি পাওয়ার অপচয় করবে। যেসব কম্পোনেন্টগুলো onPause() মেথডের ভিতর রিলিজ করে দেয়া হয় সেগুলোকে onResume() মেথডের ভিতরে initialize করা হয়। অর্থাৎ ফ্লো-টা হবে এমনঃ Activity স্ক্রিনে শো করলো। এরপর onResume() মেথডের ভিতরে ক্যামেরা ইনিশিয়ালাইজ হলো। ইউজার এই অ্যাক্টিভিটি থেকে অন্য কোনো অ্যাক্টিভিটিতে গেল। তখন আগের অ্যাক্টিভিটি ফোকাস হারিয়ে Paused State এ প্রবেশ করলো এবং onPause() মেথড কল করলো। onPause() এর ভিতর কোড লেখা থাকবে ক্যামেরাকে রিলিজ করার জন্য। ফলে ক্যামেরার জন্য বাড়তি মেমরি আর পাওয়ার খরচ হচ্ছে না। ইউজার আবার আগের অ্যাক্টিভিটিতে ফেরত আসলে onRestart(), onStart() ও onResume() মেথড কল হবে। ফলে onResume() এর ভিতরে আবারও ক্যামেরা ইনিশিয়ালাইজ হবে।

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first


    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera init
    }
}

onPause

কোনো একটা অ্যাক্টিভিটি Resumed State এ রয়েছে। এমন অবস্থায় যদি ভিউতে কোনো interruption হয় তখন onPause() কল হয়। যেমন আমাদের অ্যাক্টিভিটি onResume() এ থাকা অবস্থায় ফোনে কল আসলো। তখন default Phone App টা ওপেন হবে। আর অামাদের অ্যাক্টিভিটিটি ভিজিবল থাকবে না। এই ফোকাস হারানোর পরপরই onPause() কল হবে। অর্থাৎ সিসটেম জানান দিবে যে এই অ্যাক্টিভিটিটি অন্য কোনো অ্যাপ বা অ্যাক্টিভিটি দ্বারা ঢাকা পড়তে যাচ্ছে। এমতাবস্থায় যদি আমরা কোনো অ্যাকশন নিতে চাই সেটা যেন নিতে পারি। যেমনঃ আমাদের অ্যাক্টিভিটিতে ক্যামেরা ইউজ করে থাকলে এই কম্পোনেন্টকে যদি onResume() এ ইনিশিয়ালাইজ করে থাকি তাহলে onPause() এর ভিতরে রিলিজ করে দিতে পারি। এতে অ্যাপের পারফর্মেন্স ভাল হবে। ফোন কল শেষ করার পর default phone অ্যাপ বন্ধ হয়ে গেলে আবার আমাদের অ্যাপের অ্যাক্টিভিটিটি ভিজিবল হবে। এই ভিজিবল হবার জন্য onRestart(), onStart() ও onResume() মেথডগুলো কল হবে।

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}

Paused State থেকে অ্যাক্টিভিটি যদি আবার ভিজিবল হয়, অর্থাৎ কোনো কারণে অ্যাক্টিভিটি বন্ধ হতে গিয়েও হলো না বা Stop State এ প্রবেশ করলো না তখন সেটা ডিরেক্ট Resumed State এ প্রবেশ করে ও onResume() method কল হয়।

উদাহরণ হিসাবে উল্লেখ করা যেতে পারে সেমি ট্রান্সপারেন্ট কোনো অ্যাক্টিভিটি/পপ আপ ডায়ালগ যখন শো করে তখনকার সিচুয়েশন। ধরা যাক, অামাদের অ্যাক্টিভিটিতে একটা বাটন আছে। ক্লিক করলে একটা পপ আপ ডায়ালগ আসে। এই সময় অ্যাক্টিভিটি পুরোপুরি ভিজিবলও না আবার ইনভিজিবলও না। বলা যায় partially visible. এই অবস্থায় অ্যাক্টিভিটি Paused State এ থাকবে। এরপর যখন ডায়ালগটি ক্লোজ করে দিব তখন অ্যাক্টিভিটি Resumed State এ প্রবেশ করবে এবং onResume() মেথড কল করবে।

একই ধরনের ঘটনা ঘটবে Multi-Window Mode এ যখন একই স্ক্রিনে একাধিক অ্যাপ রান করা হয় তখন। আমরা জানি Android 7 থেকে একই সাথে স্ক্রিনে একাধিক অ্যাপ ইউজ করা যায়। স্বাভাবিক কারণেই যে কোনো একটা অ্যাপ ফোকাসে থাকবে। তখন অন্য অ্যাপটি ফোকাস হারাবে কিন্তু তখনও সেটা স্ক্রিনে ভিজিবল। সেই সময় ফোকাস হারানো অ্যাপের অ্যাক্টিভিটিটি থাকবে Paused State এ। যখন ফোকাস হারানোর ফলে Paused State এ থাকা কোনো অ্যাপ/অ্যাক্টিভিটি পুণরায় ফোকাস ফিরে পাবে তখন সেই অ্যাক্টিভিটি আবার Resumed State এ প্রবেশ করবে।

অপর পক্ষে অন্য অ্যাপ বা অ্যাক্টিভিটি দ্বারা কোনো অ্যাক্টিভিটি সম্পূর্ণ রূপে invisible হয়ে গেলে তখন সে Stopped State এ প্রবেশ করে। আর সিসটেম তখন onStop() মেথড কল করে।

মনে রাখা জরুরি, Paused State খুব সংক্ষিপ্ত সময়ের একটা স্টেট। তাই বেশি সময় লাগতে পারে এমন কাজকর্ম এই স্টেটে করা উচিত নয়। যেমনঃ ইউজারের সুবিধার জন্য অ্যাক্টিভিটির বিভিন্ন ডেটা সেভ করে রাখা, ডেটাবেজের ট্রানজেকশন বা কোনো নেটওয়ার্ক কল ইত্যাদি time consuming task কোনো ক্রমেই onPause() মেথডের ভিতর করা উচিত নয়। বিভিন্ন ধরনের ডেটা সেভ বা ডেটাবেজ ট্রানজেকশনগুলো Stopped State এ করা হয়ে থাকে।

onStop

যখন কোনো অ্যাক্টিভিটি সম্পূর্ণভাবে invisible হয়ে যায় তখন তা Stopped State এ প্রবেশ করে। তখন onStop() মেথডটি কল হয়। এই মেথডের ভিতর চাইলে ডেটা সেভ করার ছোটখাটো কাজ করা যায়। onStart() মেথডের ভিতর যেমন UI related BroadCastReceiver বা ইভেন্ট রেজিস্টার করেছিলাম, সেগুলোকে onStop() মেথডের ভিতর unregister করতে হবে। UI related বলার কারণ হচ্ছে, এমন ব্রডকাস্ট রিসিভার বা ইভেন্টকে আনরেজিস্টার করা উচিত যেগুলোর কাজ UI-কে আপডেট করা। কারণ Stopped State এ থাকার সময় UI visible থাকে না। তাই Activity invisible থাকা অবস্থায় BroadCastReciever বা অন্য কোনো ভাবে ইভেন্ট ফায়ার হলে যদি UI update করতে চেষ্টা করে তখন সেটা অ্যাপ ক্র্যাশের কারণ হতে পারে।

একটা অ্যাক্টিভিটি Stopped State থেকে অন্য দুটি স্টেটে যেতে পারে। হয় অ্যাক্টিভিটিটি আবার visible হবে। অর্থাৎ ইউজার Stop হয়ে যাওয়া অ্যাক্টিভিটিতে আবার navigate করবে; ফলে তা Restarted, Started স্টেট পার হয়ে Resumed স্টেটে প্রবেশ করবে। অন্যথায় হতে পারে অ্যাক্টিভিটিটি আর ইউজই করার দরকার হবে না তাই তাকে মেমরি থেকে রিমুভ করে দেয়ার জন্য আমরা finish() মেথড কল করে অ্যাক্টিভিটি finish করতে পারি। সেক্ষেত্রে অ্যাক্টিভিটি Destroyed State এ প্রবেশ করবে।

onRestart

Stopped State থেকে কোনো অ্যাক্টিভিটি যখন re-displayed হয় তখন প্রথমে এই মেথড কল হয়। এরপর কল হয় onStart() এবং onResume(). এই মেথডগুলো কল হবার পরই অ্যাক্টিভিটিটি আবার interactable হয়।

onDestroy

onDestroy() callback method-টি একটা অ্যাক্টিভিটির লাইফটাইমের সর্বশেষ কলব্যাক মেথড। অ্যাক্টিভিটি যেই কলব্যাক মেথডগুলো রিসিভ করে এই মেথডটি হচ্ছে তাদের মধ্যে সব শেষের কলব্যাক। যখন আমরা কোনো অ্যাক্টিভিটি রিমুভ করে দিতে চাই তখন finish() মেথড কল করে থাকি। এই মেথড কলের পর onPause(), onStop() ও শেষে onDestroy() কল হয়। এছাড়াও অ্যান্ড্রয়েড সিসটেমের তাৎক্ষণিক মেমরির প্রয়োজনে Stopped State এ থাকা কোনো Activity-কে forcefully finish করার জন্যও কল করতে পারে। সেক্ষেত্রেও একই ভাবে অ্যাক্টিভিটিটি ডেস্ট্রয় হবে ও র‍্যাম ক্লিন করে ফেলা হবে।

অামাদের অ্যাক্টিভিটিতে ইউজ করা বিভিন্ন কম্পোনেন্টগুলো যদি onPause(), onStop() এর ভিতর রিলিজ করে দিয়ে না থাকি তাহলে সেগুলোকেও onDestroy() কল হবার পর সিসটেম নিজ থেকেই রিলিজ করে দিবে। এতে র‍্যামের মেমরি অপচয় হবার কোনো আশংকা থাকে না।

প্রসঙ্গত উল্লেখ্য, অনেকে মনে করতে পারেন callback method কল হবার পরই অ্যাক্টিভিটি ঐ নির্দিষ্ট স্টেটে প্রবেশ করে। আসলে ব্যাপারটা সেরকম নয়। বরং অ্যাক্টিভিটি যখন কোনো একটা স্টেটে প্রবেশ করে ঐ মুহূর্তেই তার জন্য নির্দিষ্ট কলব্যাক মেথড কল হয়। আর ঐ মেথডের মধ্যে আমাদের প্রয়োজন অনুসারে কমান্ড দিয়ে থাকি। যেমনঃ onCreate() মেথড কল হবার পর অ্যাক্টিভিটি Created State এ প্রবেশ করে না। বরং Activity যখন Created State এ প্রবেশ করে তার কল ব্যাক মেথড হিসাবে onCreate() কল হয়। অনেকটা বাটন ক্লিকের লিসেনারের মত। বাটন ক্লিক ইভেন্ট লিসেন করার জন্য আমরা setOnClickListener() কল করে থাকি। এই মেথড কল করার ফলে বাটনে ক্লিক করতে পারলাম ব্যাপারটা কিন্তু সেরকম নয়! বরং বাটনে ক্লিক করার রেজাল্ট হিসাবে এই লিসেনার বা কলব্যাক মেথডটা কল হয়। একই রকম ভাবে অ্যাক্টিভিটি কোনো একটা স্টেটে প্রবেশ করলেই তার কলব্যাক লিসেনার হিসাবে corresponding method কল হয়।

Complete Source Code to Understand Android Activity Lifecycle

এই ব্লগপোস্টে আর কোড দিচ্ছি না। আশা করছি নিজেই অ্যাপের বিভিন্ন লাইফসাইকেল টেস্ট করতে পারবেন। এরপরেও সোর্সকোড প্রয়োজন হলে ভিজিট করুন আমার গিটহাব রিপোজিটরিতে। সেখানে অ্যাপের প্রতিটি স্টেটের কলব্যাক মেথড override করে তার ভিতরে Toast message এবং Logger Library’র মাধ্যমে লগে মেসেজ প্রিন্ট করা হয়েছে। Logger Library’র উপর ব্লগ পোস্টটি পড়তে ক্লিক করুন এখানে

অ্যাক্টিভিটি লাইফসাইকেলের উপর আরো বিস্তারিত জানা যাবে গুগলের অফিসিয়াল ডক থেকে। আমার পোস্টের কোথাও কোনো অসামঞ্জস্যতা বা ভুল চোখে পড়লে অনুগ্রহ করে শুধরে দিবেন। লেখাটি সম্পর্কে আপনার মতামত একান্ত কাম্য।

4 thoughts on “Android Activity Lifecycle

  1. সাবলীল বর্ণনা। সহজেই বুঝতে পেরেছি লাইফ সাইকেলের বিভিন্ন পর্যায়ের কাজগুলো।
    এখন প্রশ্ন হচ্ছে সব ধরনের এ্যাপেই কি লাইফ সাইকেলের প্রত্যেকটা স্টেট এক্টিভ বা ওভাররাইট করতে হয়? বিগিনিং লেভেলে যে সমস্ত এ্যাপ বিল্ড করার চেষ্টা করছি, সেগুলোতে onCreate/onStart ছাড়া আর কোনো স্টেট দেখিনি এখন পর্যন্ত।
    তাহলেকি প্রয়োজন অনুসারে স্টেটগুলো এক্টিভ বা ওভাররাইট করতে হয়? ধন্যবাদ

    1. জ্বি ভাই, যখন যেটা প্রয়োজন সেটাকে ওভাররাইড করে নিতে হয়। যেমন আপনি ক্যামেরা নিয়ে কাজ করলে দেখবেন অ্যাক্টিভিটির onPause() এ ক্যামেরার ইন্সটেন্সটা ক্লোজ করে দিচ্ছেন। ক্যামেরা নিয়ে কাজ না করলে হয়ত এই মেথড ওভাররাইড করবেনই না।

  2. অনেক ধন্যবাদ ভাই, সুন্দর করে লিখার জন্য,
    আপনার সব পোস্ট গুলাই আমি পড়ি, আপনি সব কিছু মিলাই একটা বই লিখতে পারেন ভাই এটা আমার পার্সোনাল মতামত আর কি,

    **
    অ্যান্ড্রয়েড শিখার জন্য আপনাকে বাংলা কোনো বই সাজেস্ট করতে পারবেন ভাই?

    1. Android বা যে কোনো ফ্রেমওয়ার্কের উপর বই লিখা আসলে লস প্রোজেক্ট। কারণ প্রতিনিয়ত ফ্রেমওয়ার্ক পরিবর্তন হতে থাকে। তার সাথে পাল্লা দিয়ে বই আপডেট করা যায় না। তাই এগুলোর জন্য ব্লগই বেশি ফিজিবল মনে করি।

      অ্যান্ড্রয়েডের জন্য বাংলায় কোনো বই আছে কিনা আমার জানা নাই।

Leave a Reply

Your email address will not be published. Required fields are marked *