অ্যাক্টিভিটি লাইফসাইকেল

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

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

প্রতিটি কলব্যাক আপনাকে নির্দিষ্ট কাজ করতে দেয় যা প্রদত্ত স্টেট পরিবর্তনের জন্য উপযুক্ত। সঠিক সময়ে সঠিক কাজ করা এবং ট্রানজিশন সঠিকভাবে ম্যানেজ করা আপনার অ্যাপকে আরও শক্তিশালী ও পারফর্ম্যান্স-ভিত্তিক করে তোলে। যেমন, লাইফসাইকেল কলব্যাক সঠিকভাবে ইমপ্লিমেন্ট করলে, আপনার অ্যাপ নিম্নলিখিত বিষয়গুলি এড়াতে পারবে:

  • ব্যবহারকারী আপনার অ্যাপ ব্যবহার করার সময় ফোন কল পেলে বা অন্য অ্যাপে সুইচ করলে ক্র্যাশ করা।
  • ব্যবহারকারী সক্রিয়ভাবে ব্যবহার না করলেও মূল্যবান সিস্টেম রিসোর্স ব্যবহার করা।
  • ব্যবহারকারী আপনার অ্যাপ ছেড়ে চলে গেলে এবং পরে ফিরে এলে তার প্রোগ্রেস হারিয়ে যাওয়া।
  • স্ক্রিন ল্যান্ডস্কেপ ও পোর্ট্রেট ওরিয়েন্টেশনের মধ্যে রোটেট করলে ক্র্যাশ করা বা ব্যবহারকারীর অগ্রগতি হারিয়ে যাওয়া।

এই ডকুমেন্টে অ্যাক্টিভিটি লাইফসাইকেল বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে। ডকুমেন্টটি লাইফসাইকেল প্যারাডাইম বর্ণনা করার মাধ্যমে শুরু হয়। এরপরে, এটি প্রতিটি কলব্যাকের ব্যাখ্যা করে: সেগুলি এক্সিকিউট করার সময় ইন্টার্নালি কী ঘটে এবং সেগুলি চলাকালীন আপনাকে কী ইমপ্লিমেন্ট করতে হবে।

তারপরে, এটি অ্যাক্টিভিটি স্টেট এবং সিস্টেমের দ্বারা কিল করার জন্য প্রসেসের দুর্বলতার মধ্যে সম্পর্ককে সংক্ষিপ্তভাবে পরিচয় করিয়ে দেয়। সবশেষে, এটি অ্যাক্টিভিটি স্টেটের মধ্যে ট্রানজিশন সম্পর্কিত বিভিন্ন বিষয় নিয়ে আলোচনা করে।

পেশাদার পদ্ধতি সহ লাইফসাইকেল ম্যানেজ করা সম্পর্কে তথ্য পেতে, Jetpack Compose-এ লাইফসাইকেল ও UI স্টেট সেভ করা দেখুন। আর্কিটেকচার কম্পোনেন্টের সাথে অ্যাক্টিভিটি ব্যবহার করে কীভাবে একটি শক্তিশালী, প্রোডাকশন-কোয়ালিটি অ্যাপ তৈরি করতে হয় তা জানতে, অ্যাপ আর্কিটেকচার সংক্রান্ত গাইড দেখুন।

অ্যাক্টিভিটি-লাইফসাইকেল কনসেপ্ট

অ্যাক্টিভিটি লাইফসাইকেলের বিভিন্ন স্টেজের মধ্যে ট্রানজিশন নেভিগেট করতে, Activity ক্লাস ছয়টি কলব্যাকের একটি মূল সেট প্রদান করে: onCreate, onStart, onResume, onPause, onStop এবং onDestroy. অ্যাক্টিভিটি নতুন স্টেটে প্রবেশ করলে সিস্টেম এইসব কলব্যাককে ইনভোক করে।

ছবি ১-এ এই প্যারাডাইমের একটি ভিজ্যুয়াল উপস্থাপনা দেখানো হয়েছে।

ছবি ১. অ্যাক্টিভিটি লাইফসাইকেলের একটি সরলীকৃত ইলাস্ট্রেশন।

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

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

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

আপনার অ্যাক্টিভিটির জটিলতার উপর নির্ভর করে, আপনাকে সম্ভবত সব লাইফসাইকেল পদ্ধতি ইমপ্লিমেন্ট করতে হবে না। তবে, প্রত্যেকটি বোঝা এবং ব্যবহারকারীরা যেভাবে আপনার অ্যাপ ব্যবহার করতে চান সেইভাবে অ্যাপকে আচরণ করতে সাহায্য করে এমনগুলি প্রয়োগ করা গুরুত্বপূর্ণ।

Compose ও লাইফসাইকেল

Compose-এ, onStart বা onResume-এর মতো অ্যাক্টিভিটি কলব্যাক ফাংশনের মধ্যে সরাসরি বিজনেস লজিক বা ম্যানুয়াল অবজারভার সেট-আপ প্লেস করা এড়িয়ে চলুন। পরিবর্তে, এমন লাইফসাইকেল-সচেতন এফেক্ট ও স্টেট-সচেতন অবজারভার ব্যবহার করুন যা স্ক্রিনে UI-এর উপস্থিতি অনুযায়ী অটোমেটিক অ্যালাইন হয়ে যায়।

  • লাইফসাইকেল-সচেতন সংগ্রহ: আপনার ViewModel থেকে ফ্লো কনজিউম করতে collectAsStateWithLifecycle ব্যবহার করুন। UI যখন 'শুরু হয়েছে' স্টেটে প্রবেশ করে, তখন এই API অটোমেটিক ডেটা সংগ্রহ করা শুরু করে এবং ব্যাকগ্রাউন্ডে চলে গেলে তা বন্ধ হয়ে যায়। এর ফলে অপ্রয়োজনীয় রিসোর্স ব্যবহার করা আটকানো যায়। স্টেট হিসেবে ফ্লো সংগ্রহ করার পরে, কোনও লাইফসাইকেল ইভেন্ট ঘটলে কোড রান করাতে আপনি LifecycleEffects ব্যবহার করতে পারেন।
  • লজিকের ফ্লো: এইসব API ব্যবহার করে, UI কম্পোজিশন ট্রি-এর মাধ্যমে লাইফসাইকেল স্টেটে স্বাভাবিকভাবে প্রতিক্রিয়া জানায়, এর ফলে ব্যবহারকারী কম্পোনেন্টের সাথে অ্যাক্টিভভাবে ইন্টার‍্যাক্ট করলেই শুধুমাত্র বিজনেস লজিক এক্সিকিউট হয়।

Compose ও লাইফসাইকেল সম্পর্কে আরও জানতে, Jetpack Compose-এ লাইফসাইকেল দেখুন।

লাইফসাইকেল কলব্যাক

অ্যাক্টিভিটি লাইফসাইকেলে ব্যবহৃত কলব্যাক পদ্ধতি সম্পর্কে এই বিভাগে ধারণা ও প্রয়োগ সংক্রান্ত তথ্য দেওয়া হয়েছে।

কিছু অ্যাকশন অ্যাক্টিভিটি লাইফসাইকেল পদ্ধতির মধ্যে পড়ে। তবে, অ্যাক্টিভিটি লাইফসাইকেল পদ্ধতির পরিবর্তে কম্পোনেন্টে, কোনও ডিপেন্ডেন্ট কম্পোনেন্টের অ্যাকশন ইমপ্লিমেন্ট করে এমন কোড প্লেস করুন। এটি করতে, আপনাকে ডিপেন্ডেন্ট কম্পোনেন্টকে লাইফসাইকেল-সচেতন করে তুলতে হবে। কীভাবে আপনার নির্ভরশীল কম্পোনেন্টকে লাইফসাইকেল-অ্যাওয়ার করতে হয় তা জানতে, Jetpack Compose-এ লাইফসাইকেল দেখুন।

onCreate

সিস্টেম প্রথমবার অ্যাক্টিভিটি তৈরি করলে এই কলব্যাক ফায়ার হয়, আপনাকে এটি প্রয়োগ করতে হবে। অ্যাক্টিভিটি তৈরি করার পরে, অ্যাক্টিভিটি তৈরি করা হয়েছে স্ট্যাটাসে চলে যায়। onCreate পদ্ধতিতে, সাধারণ অ্যাপ্লিকেশন স্টার্ট-আপ লজিক পারফর্ম করুন যা অ্যাক্টিভিটির সম্পূর্ণ লাইফসাইকেলে শুধুমাত্র একবার ঘটে।

যেমন, আপনার onCreate প্রয়োগ করার ফলে ডেটা তালিকাভুক্ত হতে পারে, অ্যাক্টিভিটি ViewModel-এর সাথে যুক্ত হতে পারে এবং কিছু ক্লাস-স্কোপ ভেরিয়েবল ইনস্ট্যানশিয়েট হতে পারে। এই পদ্ধতিতে savedInstanceState প্যারামিটারটি পাওয়া যায়, এটি হল Bundle অবজেক্ট যাতে অ্যাক্টিভিটির আগে সেভ করা স্টেট থাকে। অ্যাক্টিভিটি আগে কখনও না হয়ে থাকলে, Bundle অবজেক্টের ভ্যালু শূন্য হয়।

আপনার অ্যাক্টিভিটির লাইফসাইকেলের সাথে হুক করা কোনও লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্ট থাকলে, এটি ON_CREATE ইভেন্ট পায়। @OnLifecycleEvent দিয়ে অ্যানোটেশন করা পদ্ধতিকে কল করা হয় যাতে আপনার লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্ট তৈরি করা স্টেটের জন্য প্রয়োজনীয় যেকোনও সেট-আপ কোড পারফর্ম করতে পারে।

নিচের উদাহরণে দেখানো হয়েছে কীভাবে Text কম্পোজ করার উপযুক্ত কোডকে একেবারে ন্যূনতম অ্যাক্টিভিটির সাথে ইন্টিগ্রেট করতে হয়:

class ExampleActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent { // In here, we can call composables!
            MaterialTheme {
                Greeting(name = "compose")
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

আপনার অ্যাক্টিভিটি 'তৈরি করা হয়েছে' অবস্থায় থাকে না। onCreate পদ্ধতি সম্পন্ন হওয়ার পরে, অ্যাক্টিভিটি শুরু করা হয়েছে স্টেটে প্রবেশ করে এবং সিস্টেম দ্রুত পরপর onStart ও onResume পদ্ধতি কল করে।

onStart

অ্যাক্টিভিটি 'শুরু হয়েছে' স্টেটে প্রবেশ করলে, সিস্টেম onStart ইনভোক করে। এই কলটি ব্যবহারকারীর কাছে অ্যাক্টিভিটি দৃশ্যমান করে তোলে কারণ অ্যাপটি অ্যাক্টিভিটিকে ফোরগ্রাউন্ডে প্রবেশ করতে এবং ইন্ট্যার‍্যাক্টিভ হয়ে উঠতে প্রস্তুত করে। যেমন, এই মেথড হল সেই জায়গা যেখানে UI বজায় রাখে এমন কোড ইনিশিয়ালাইজ করা হয়।

অ্যাক্টিভিটি যখন 'শুরু হয়েছে' স্টেটে চলে যায়, তখন অ্যাক্টিভিটির লাইফসাইকেলের সাথে যুক্ত যেকোনও লাইফসাইকেল-সচেতন কম্পোনেন্ট ON_START ইভেন্ট পায়।

onStart পদ্ধতিটি দ্রুত সম্পূর্ণ হয় এবং Created স্টেটের মতো, অ্যাক্টিভিটি Started স্টেটে থাকে না। এই কলব্যাক শেষ হয়ে গেলে, অ্যাক্টিভিটি আবার চালু করা হয়েছে স্ট্যাটাসে চলে যায় এবং সিস্টেম onResume মেথডকে ইনভোক করে।

onResume

অ্যাক্টিভিটি আবার চালু হলে, সেটি ফোরগ্রাউন্ডে চলে আসে এবং সিস্টেম onResume কলব্যাক ইনভোক করে। এটি হল সেই অবস্থা যেখানে অ্যাপ ব্যবহারকারীর সাথে ইন্টার‍্যাক্ট করে। ডিভাইসে ফোন কল এলে, ব্যবহারকারী অন্য অ্যাক্টিভিটিতে নেভিগেট করলে বা ডিভাইসের স্ক্রিন বন্ধ হয়ে গেলে, অ্যাপের ফোকাস সরে যায়। এইসব ঘটনা না ঘটা পর্যন্ত অ্যাপটি এই অবস্থায় থাকে।

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

কোনও বাধা সৃষ্টিকারী ইভেন্ট ঘটলে, অ্যাক্টিভিটি পজ করা অবস্থায় চলে যায় এবং সিস্টেম onPause কলব্যাককে ইনভোক করে।

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

এখানে লাইফসাইকেল-সচেতন কম্পোনেন্টের একটি উদাহরণ দেওয়া হল যা কম্পোনেন্ট ON_RESUME ইভেন্ট পেলে ক্যামেরা অ্যাক্সেস করে:

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun initializeCamera() {
        if (camera == null) {
            getCamera()
        }
    }
    ...
}

LifecycleObserver ON_RESUME ইভেন্ট পেলে আগের কোডটি ক্যামেরা ইনিশিয়ালাইজ করে। তবে, মাল্টি-উইন্ডো মোডে, আপনার অ্যাক্টিভিটি পজ করা অবস্থায় থাকলেও সম্পূর্ণভাবে দেখা যেতে পারে। যেমন, অ্যাপটি মাল্টি-উইন্ডো মোডে থাকলে এবং ব্যবহারকারী এমন উইন্ডোতে ট্যাপ করলে যেখানে আপনার অ্যাক্টিভিটি নেই, আপনার অ্যাক্টিভিটি পজ করা অবস্থায় চলে যায়।

আপনি যদি চান যে অ্যাপটি আবার চালু (ফোরগ্রাউন্ডে দেখা যাচ্ছে এবং অ্যাক্টিভ ) হলে তবেই ক্যামেরা অ্যাক্টিভ থাকুক, তাহলে আগে দেখানো ON_RESUME ইভেন্টের পরে ক্যামেরা ইনিশিয়ালাইজ করুন। অ্যাক্টিভিটি পজ করা থাকলেও, আপনি যদি ক্যামেরা চালু রাখতে চান, যেমন মাল্টি-উইন্ডো মোডে, তাহলে ON_START ইভেন্টের পরে ক্যামেরা ইনিশিয়ালাইজ করুন।

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

এই কারণে, মাল্টি-উইন্ডো মোডের প্রসঙ্গে শেয়ার করা সিস্টেম রিসোর্সের কন্ট্রোল নেওয়ার জন্য লাইফসাইকেলের কোন পয়েন্ট সবচেয়ে উপযুক্ত তা ভালোভাবে ভেবে দেখুন। মাল্টি-উইন্ডো মোড কাজ করে এমন ডিভাইস সম্পর্কে আরও জানতে, মাল্টি-উইন্ডো মোড কাজ করে দেখুন।

আপনি যে বিল্ড-আপ ইভেন্টেই ইনিশিয়ালাইজেশন অপারেশন পারফর্ম করুন না কেন, রিসোর্স রিলিজ করার জন্য সংশ্লিষ্ট লাইফসাইকেল ইভেন্ট ব্যবহার করতে ভুলবেন না। ON_START ইভেন্টের পরে কিছু ইনিশিয়ালাইজ করলে, ON_STOP ইভেন্টের পরে সেটি রিলিজ বা টারমিনেট করুন। আপনি যদি ON_RESUME ইভেন্টের পরে ইনিশিয়ালাইজ করেন, তাহলে ON_PAUSE ইভেন্টের পরে রিলিজ করুন।

পূর্ববর্তী কোড স্নিপেটটি লাইফসাইকেল-সচেতন কম্পোনেন্টে ক্যামেরা ইনিশিয়ালাইজেশন কোড প্লেস করে। আপনি এর পরিবর্তে এই কোডটি সরাসরি অ্যাক্টিভিটি লাইফসাইকেল কলব্যাক, যেমন onStart এবং onStop-এ রাখতে পারেন, তবে আমরা এটি সাজেস্ট করি না। লাইফসাইকেল সম্পর্কে সচেতন, এমন স্বতন্ত্র কম্পোনেন্টে এই লজিক যোগ করলে, কোড ডুপ্লিকেট না করেই একাধিক অ্যাক্টিভিটি জুড়ে কম্পোনেন্টটি পুনর্ব্যবহার করতে পারবেন। লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্ট কীভাবে তৈরি করতে হয় তা জানতে, Jetpack Compose-এ লাইফসাইকেল দেখুন।

onPause

ব্যবহারকারী আপনার অ্যাক্টিভিটি ছেড়ে যাচ্ছেন, সিস্টেম এই পদ্ধতির মাধ্যমে প্রথমবার তা বুঝতে পারে। তবে এর অর্থ এই নয় যে অ্যাক্টিভিটি বন্ধ হয়ে যাচ্ছে। এটি ইঙ্গিত করে যে অ্যাক্টিভিটি আর ফোরগ্রাউন্ডে নেই, তবে ব্যবহারকারী মাল্টি-উইন্ডো মোডে থাকলে এটি এখনও দেখা যাবে। কোনও অ্যাক্টিভিটি এই অবস্থায় যাওয়ার একাধিক কারণ থাকতে পারে:

  • onResume কলব্যাক সম্পর্কে বিভাগে বর্ণিত অ্যাপ এক্সিকিউশনকে বাধাগ্রস্ত করে এমন কোনও ইভেন্ট, বর্তমান অ্যাক্টিভিটি পজ করে। এটি হল সবচেয়ে সাধারণ ঘটনা।
  • মাল্টি-উইন্ডো মোডে, যেকোনও সময় শুধুমাত্র একটি অ্যাপে ফোকাস করা হয় এবং সিস্টেম অন্যান্য সব অ্যাপ পজ করে দেয়।
  • নতুন, আংশিক স্বচ্ছ অ্যাক্টিভিটি, যেমন ডায়ালগ খুললে, এটি যে অ্যাক্টিভিটিকে ঢেকে দেয় সেটি পজ হয়ে যায়। যতক্ষণ অ্যাক্টিভিটি আংশিকভাবে দেখা যাচ্ছে কিন্তু ফোকাসে নেই, ততক্ষণ এটি পজ করা থাকবে।

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

Activity পজ করা অবস্থায় থাকলে, যে অপারেশন চালিয়ে যাওয়া যায় না, অথবা সীমিতভাবে চালিয়ে যাওয়া যেতে পারে, সেগুলি পজ বা অ্যাডজাস্ট করতে onPause পদ্ধতি ব্যবহার করুন এবং আপনি শীঘ্রই সেগুলি আবার চালু করতে চান।

এছাড়াও, সিস্টেম রিসোর্স, হ্যান্ডেল থেকে সেন্সর (যেমন, GPS) বা এমন যেকোনও রিসোর্স রিলিজ করতে আপনি onPause পদ্ধতি ব্যবহার করতে পারেন যা আপনার অ্যাক্টিভিটি পজ করা থাকলে ব্যাটারির আয়ুকে প্রভাবিত করে এবং ব্যবহারকারীর সেগুলির প্রয়োজন হয় না।

তবে, onResume সম্পর্কে বিভাগে উল্লেখ করা হয়েছে যে, অ্যাপটি মাল্টি-উইন্ডো মোডে থাকলে পজ করা অ্যাক্টিভিটি সম্পূর্ণভাবে দৃশ্যমান হতে পারে। মাল্টি-উইন্ডো মোডকে আরও ভালোভাবে সাপোর্ট করতে, UI-সম্পর্কিত রিসোর্স ও অপারেশন সম্পূর্ণ রিলিজ বা অ্যাডজাস্ট করার জন্য onPause-এর পরিবর্তে onStop ব্যবহার করার কথা বিবেচনা করুন।

ON_PAUSE ইভেন্টের প্রতি LifecycleObserver-এর প্রতিক্রিয়া দেখানোর নিম্নলিখিত উদাহরণটি হল পূর্ববর্তী ON_RESUME ইভেন্টের উদাহরণ, যা ON_RESUME ইভেন্ট পাওয়ার পরে ক্যামেরা চালু করে:

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun releaseCamera() {
        camera?.release()
        camera = null
    }
    ...
}

এই উদাহরণে, LifecycleObserver-এর দ্বারা ON_PAUSE ইভেন্ট পাওয়ার পরে ক্যামেরা রিলিজ কোডটি প্লেস করা হয়েছে।

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

পরিবর্তে, onStop-এর সময় হেভি-লোড শাটডাউন অপারেশন পারফর্ম করুন। onStop-এর সময় উপযুক্ত অপারেশন পারফর্ম করা সম্পর্কে আরও তথ্য পেতে, পরবর্তী বিভাগ দেখুন। ডেটা সেভ করা সম্পর্কে আরও জানতে, সেভ করা ও আগের অবস্থায় ফিরিয়ে আনা সংক্রান্ত বিভাগ দেখুন।

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

অ্যাক্টিভিটি পজ করা অবস্থা থেকে আবার চালু করা হলে, সিস্টেম Activity ইনস্ট্যান্স মেমরিতে রেখে দেয় এবং সিস্টেম onResume ইনভোক করলে সেই ইনস্ট্যান্স রিকল করে। এই পরিস্থিতিতে, আপনাকে আবার শুরু করার আগে কলব্যাক পদ্ধতিতে তৈরি করা কম্পোনেন্ট আবার ইনিশিয়ালাইজ করতে হবে না। অ্যাক্টিভিটি সম্পূর্ণ অদৃশ্য হয়ে গেলে, সিস্টেম onStop-এ কল করে।

onStop

ব্যবহারকারী যখন আপনার অ্যাক্টিভিটি আর দেখতে পান না, তখন এটি বন্ধ করা স্টেটে চলে যায় এবং সিস্টেম onStop কলব্যাককে ইনভোক করে। নতুন লঞ্চ করা অ্যাক্টিভিটি সম্পূর্ণ স্ক্রিন জুড়ে থাকলে এটি হতে পারে। এছাড়াও, অ্যাক্টিভিটি রান করা শেষ হয়ে গেলে এবং সেটি বন্ধ করার আগে সিস্টেম onStop কল করে।

অ্যাক্টিভিটি যখন 'বন্ধ করা' স্টেটে চলে যায়, তখন অ্যাক্টিভিটির লাইফসাইকেলের সাথে যুক্ত যেকোনও লাইফসাইকেল-সচেতন কম্পোনেন্ট ON_STOP ইভেন্ট পায়। কম্পোনেন্ট স্ক্রিনে দেখা না গেলে, লাইফসাইকেল কম্পোনেন্ট এমন যেকোনও ফাংশনালিটি বন্ধ করে দিতে পারে যেটি চালানোর প্রয়োজন নেই।

onStop পদ্ধতিতে, অ্যাপ ব্যবহারকারীকে না দেখানোর সময় অপ্রয়োজনীয় রিসোর্স রিলিজ বা অ্যাডজাস্ট করুন। যেমন, আপনার অ্যাপ অ্যানিমেশন পজ করতে পারে অথবা সুনির্দিষ্ট লোকেশন আপডেট থেকে অনির্দিষ্ট লোকেশন আপডেটে পরিবর্তন করতে পারে। onPause-এর পরিবর্তে onStop ব্যবহার করার অর্থ হল, ব্যবহারকারী মাল্টি-উইন্ডো মোডে আপনার অ্যাক্টিভিটি দেখলেও UI-সম্পর্কিত কাজ চলতে থাকে।

এছাড়াও, তুলনামূলকভাবে CPU-ইনটেনসিভ শাটডাউন অপারেশন পারফর্ম করতে onStop ব্যবহার করুন। যেমন, আপনি যদি ডেটাবেসে তথ্য সেভ করার জন্য আরও ভালো সময় খুঁজে না পান, তাহলে onStop-এর সময় তা করতে পারেন। নিচের উদাহরণে onStop-এর প্রয়োগ দেখানো হয়েছে যা কোনও ড্রাফ্ট নোটের কন্টেন্টকে পারসিস্টেন্ট স্টোরেজে সেভ করে:

override fun onStop() {
    super.onStop()

    // Delegate the save operation to the ViewModel, which handles the
    // background thread operations (e.g., using Kotlin Coroutines and Room).
    noteViewModel.saveDraft()
}

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

বন্ধ হয়ে যাওয়া অবস্থা থেকে, অ্যাক্টিভিটি হয় ব্যবহারকারীর সাথে ইন্টার‍্যাক্ট করার জন্য ফিরে আসে, অথবা অ্যাক্টিভিটি রান করা শেষ হয়ে যায় এবং চলে যায়। অ্যাক্টিভিটি আবার ফিরে এলে, সিস্টেম onRestart ইনভোক করে। Activity শেষ হয়ে গেলে, সিস্টেম onDestroy কল করে।

onDestroy

অ্যাক্টিভিটি ধ্বংস করার আগে onDestroy কল করা হয়। দুটি কারণের মধ্যে একটির জন্য সিস্টেম এই কলব্যাককে আহ্বান করে:

  1. ব্যবহারকারী অ্যাক্টিভিটি সম্পূর্ণ ডিসমিস করে দেওয়ায় অথবা অ্যাক্টিভিটিতে finish কল করা হলে অ্যাক্টিভিটি শেষ হয়ে যায়।
  2. কনফিগারেশন পরিবর্তনের কারণে সিস্টেম সাময়িকভাবে অ্যাক্টিভিটি ধ্বংস করছে, যেমন ডিভাইস রোটেট করা বা মাল্টি-উইন্ডো মোডে প্রবেশ করা।

অ্যাক্টিভিটি যখন ডেস্ট্রয়েড স্টেটে চলে যায়, তখন অ্যাক্টিভিটির লাইফসাইকেলের সাথে যুক্ত যেকোনও লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্ট ON_DESTROY ইভেন্ট পায়। এখানেই লাইফসাইকেল কম্পোনেন্ট, Activity ধ্বংস হওয়ার আগে প্রয়োজনীয় যেকোনও কিছু ক্লিন-আপ করতে পারে।

আপনার Activity ধ্বংস হওয়ার কারণ নির্ধারণ করতে, সেটিতে লজিক না রেখে, Activity-এর জন্য প্রাসঙ্গিক ভিউ ডেটা ধারণ করতে ViewModel অবজেক্ট ব্যবহার করুন। কনফিগারেশনে পরিবর্তনের কারণে Activity আবার তৈরি করা হলে, ViewModel-কে কিছু করতে হবে না, কারণ এটি সংরক্ষিত থাকে এবং পরবর্তী Activity ইনস্ট্যান্সকে দেওয়া হয়।

Activity আবার তৈরি না হলে, ViewModel-এর onCleared মেথড কল করা হয়, যেখানে এটি ধ্বংস হওয়ার আগে প্রয়োজনীয় ডেটা ক্লিন-আপ করতে পারে। আপনি isFinishing পদ্ধতির মাধ্যমে এই দুটি পরিস্থিতির মধ্যে পার্থক্য করতে পারবেন।

অ্যাক্টিভিটি শেষ হয়ে গেলে, onDestroy হল অ্যাক্টিভিটি পাওয়া শেষ লাইফসাইকেল কলব্যাক। কনফিগারেশন পরিবর্তনের ফলে onDestroy কল করা হলে, সিস্টেম সঙ্গে সঙ্গে একটি নতুন অ্যাক্টিভিটি ইনস্ট্যান্স তৈরি করে এবং তারপরে নতুন কনফিগারেশনে সেই নতুন ইনস্ট্যান্সে onCreate কল করে।

onDestroy কলব্যাক, onStop-এর মতো আগের কলব্যাক রিলিজ না করা সব রিসোর্স রিলিজ করে।

অ্যাক্টিভিটির অবস্থা ও মেমরি থেকে তা সরিয়ে দেওয়া

RAM খালি করার প্রয়োজন হলে সিস্টেম প্রসেস বন্ধ করে দেয়। সিস্টেম কোনও নির্দিষ্ট প্রসেস বন্ধ করে দেবে কিনা তা সেই সময় প্রসেসের অবস্থার উপর নির্ভর করে। প্রসেস স্টেট, পরিবর্তে, প্রসেসে রান করা অ্যাক্টিভিটির স্টেটের উপর নির্ভর করে। সারণী ১-এ প্রসেস স্টেট, অ্যাক্টিভিটি স্টেট এবং সিস্টেমের প্রসেস কিল করার সম্ভাবনার মধ্যে পারস্পরিক সম্পর্ক দেখানো হয়েছে। এই সারণীটি শুধুমাত্র তখনই প্রযোজ্য হয় যদি কোনও প্রসেস অন্য ধরনের অ্যাপ্লিকেশন কম্পোনেন্ট না চালায়।

হত্যা হওয়ার সম্ভাবনা

প্রসেস স্টেট

ফাইনাল অ্যাক্টিভিটি স্টেট

সর্বনিম্ন

ফোরগ্রাউন্ড (ফোকাস আছে বা পেতে চলেছে)

পুনরায় শুরু করেছেন

কম

দৃশ্যমান (কোনও ফোকাস নেই)

শুরু/পজ করা হয়েছে

আরও ভাল

ব্যাকগ্রাউন্ড (অদৃশ্য)

থামানো হয়েছে

সর্বোচ্চ

ফাঁকা

ধ্বংস করা হয়েছে

সারণী ১. প্রসেস লাইফসাইকেল ও অ্যাক্টিভিটি স্টেটের মধ্যে সম্পর্ক।

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

এছাড়াও, ব্যবহারকারী সংশ্লিষ্ট অ্যাপ বন্ধ করতে, সেটিংসের অধীনে অ্যাপ্লিকেশন ম্যানেজার ব্যবহার করে কোনও প্রসেস বন্ধ করতে পারেন।

প্রসেস সম্পর্কে আরও জানতে, প্রসেস ও থ্রেডের ওভারভিউ দেখুন।

ক্ষণস্থায়ী UI স্টেট সেভ ও রিস্টোর করা

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

একইভাবে, কোনও ব্যবহারকারী যদি সাময়িকভাবে আপনার অ্যাপ থেকে অন্য অ্যাপে যান এবং পরে আপনার অ্যাপে ফিরে আসেন, তাহলে তিনি আশা করেন যে UI স্টেট একই থাকবে। তবে, ব্যবহারকারী যখন দূরে থাকেন এবং আপনার অ্যাক্টিভিটি বন্ধ থাকে, তখন সিস্টেম আপনার অ্যাপ্লিকেশনের প্রসেস বন্ধ করে দিতে পারে।

সিস্টেমের সীমাবদ্ধতার কারণে অ্যাক্টিভিটি ধ্বংস হয়ে গেলে, ViewModel (জটিল ব্যবসায়িক লজিক ও স্ক্রিন স্টেট), Jetpack Compose rememberSaveable API (লাইটওয়েট UI স্টেট) এবং/অথবা লোকাল স্টোরেজের মাধ্যমে ব্যবহারকারীর ক্ষণস্থায়ী UI স্টেট সেভ করুন। সিস্টেমের আচরণ এবং সিস্টেম-ইনিশিয়েটেড অ্যাক্টিভিটি ও প্রসেস ডেথ জুড়ে জটিল UI স্টেট ডেটা কীভাবে সবচেয়ে ভালভাবে সংরক্ষণ করা যায় সেই সম্পর্কে ব্যবহারকারীর প্রত্যাশা সম্পর্কে আরও জানতে, UI স্টেট সেভ করুন দেখুন।

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

ইনস্ট্যান্সের স্ট্যাটাস

কিছু পরিস্থিতি আছে যেখানে সাধারণ অ্যাপ বিহেভিয়ারের কারণে আপনার অ্যাক্টিভিটি ধ্বংস হয়ে যায়, যেমন ব্যবহারকারী 'ফিরে যান' বোতাম প্রেস করলে অথবা আপনার অ্যাক্টিভিটি finish মেথড কল করে নিজেই ধ্বংস হয়ে গেলে।

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

তবে, সিস্টেমের সীমাবদ্ধতার কারণে (যেমন, কনফিগারেশনে পরিবর্তন বা মেমরি প্রেসার) সিস্টেম অ্যাক্টিভিটি ধ্বংস করে দিলে, যদিও আসল Activity ইনস্ট্যান্সটি আর থাকে না, সিস্টেম মনে রাখে যে এটি ছিল। ব্যবহারকারী যদি অ্যাক্টিভিটিতে ফিরে যাওয়ার চেষ্টা করেন, তাহলে সিস্টেম সেভ করা ডেটার একটি সেট ব্যবহার করে সেই অ্যাক্টিভিটির একটি নতুন ইনস্ট্যান্স তৈরি করে। এই ডেটা অ্যাক্টিভিটি ধ্বংস হয়ে যাওয়ার সময় তার অবস্থা বর্ণনা করে।

আগের অবস্থা ফিরিয়ে আনতে সিস্টেম যে সেভ করা ডেটা ব্যবহার করে, তাকে ইনস্ট্যান্স স্টেট বলা হয়। এটি আসলে কী-ভ্যালু পেয়ারের একটি সংগ্রহ। ডিফল্ট হিসেবে, সিস্টেম আপনার UI লেআউট সম্পর্কে প্রাথমিক তথ্য সেভ করতে ইনস্ট্যান্স স্টেট ব্যবহার করে, যেমন ব্যবহারকারীর টেক্সট ইনপুট বা স্ক্রল পজিশন।

আপনি rememberSaveable ব্যবহার করে এই সিস্টেমের আচরণে হুক করেন। আপনার অ্যাক্টিভিটি ইনস্ট্যান্স ধ্বংস হয়ে গেলে এবং আবার তৈরি হলে, rememberSaveable-এ র‍্যাপ করা যেকোনও UI স্টেট অটোমেটিক রিস্টোর হয়ে যায়, এর জন্য আপনাকে কোনও অতিরিক্ত অ্যাক্টিভিটি-লেভেল কোড লিখতে হয় না।

তবে, আপনার অ্যাক্টিভিটিতে সম্ভবত আরও জটিল স্টেট তথ্য থাকবে যা আপনি রিস্টোর করতে চান, যেমন ব্যবহারকারীর ডেটা, নেটওয়ার্কের উত্তর বা মেম্বার ভেরিয়েবল যা ব্যবহারকারীর প্রগ্রেস ট্র্যাক করে। ইনস্ট্যান্স স্টেট মেকানিজম (এবং, এর সাথে সাথে, rememberSaveable) তুচ্ছ পরিমাণের চেয়ে বেশি ডেটা সেভ করার জন্য উপযুক্ত নয়, কারণ এর জন্য মূল থ্রেডে সিরিয়ালাইজেশন প্রয়োজন হয় এবং এটি সিস্টেম-প্রসেস মেমরি ব্যবহার করে।

খুব অল্প পরিমাণের চেয়ে বেশি ডেটা সেভ করতে, UI স্টেট সেভ করুন নিবন্ধে বর্ণিত পারসিস্টেন্ট লোকাল স্টোরেজ, ViewModel ক্লাস ও কম্পোজ স্টেট হোইস্টিং ব্যবহার করে একটি সম্মিলিত পদ্ধতি নিন।

rememberSaveable ব্যবহার করে সাধারণ, হালকা UI স্টেট সেভ করা

আপনার অ্যাক্টিভিটি বন্ধ হতে শুরু করলে, সিস্টেম একটি ইনস্ট্যান্স স্টেট বান্ডেলে স্টেট সংক্রান্ত তথ্য সেভ করার জন্য প্রস্তুতি নেয়। এই সিস্টেমের আচরণে হুক করার জন্য, আপনার কম্পোজ করার উপযুক্ত ফাংশনের মধ্যে সরাসরি rememberSaveable ব্যবহার করুন। rememberSaveable অ্যাক্টিভিটি রিক্রিয়েশন জুড়ে ব্যবহারকারীর টেক্সট ইনপুট বা স্ক্রল পজিশনের মতো ক্ষণস্থায়ী UI স্টেট অটোমেটিক সেভ ও রিস্টোর করে।

কাস্টম, হালকা ওজনের স্টেট সংক্রান্ত তথ্য (যেমন, কোনও গেমে ব্যবহারকারীর অগ্রগতি) সেভ করতে, rememberSaveable ব্যবহার করে আপনার স্টেট ঘোষণা করুন। Compose ফ্রেমওয়ার্ক ইনস্ট্যান্স স্টেট বান্ডেলে সিরিয়ালাইজেশন গোপনে ম্যানেজ করে:

var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) {
    mutableStateOf(
        TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length))
    )
}

স্থায়ী ডেটা সেভ করতে, যেমন ব্যবহারকারীর পছন্দ বা কোনও ডেটাবেসের ডেটা, আপনার অ্যাক্টিভিটি ফোরগ্রাউন্ডে থাকাকালীন উপযুক্ত সুযোগ নিন। এই ধরনের কোনও সুযোগ না থাকলে, onStop পদ্ধতির সময় পারসিস্টেন্ট ডেটা সেভ করুন।

সেভ করা ইনস্ট্যান্স স্টেট ব্যবহার করে অ্যাক্টিভিটি UI স্টেট ফিরিয়ে আনা

আগে ধ্বংস হয়ে যাওয়ার পরে আপনার অ্যাক্টিভিটি আবার তৈরি করা হলে, স্টেট রিস্টোরেশন অটোমেটিক হয়। আপনি rememberSaveable ব্যবহার করলে, আপনাকে কোনও স্পষ্ট রিস্টোরেশন লজিক লিখতে হবে না, নাল বান্ডেল চেক করতে হবে না অথবা অ্যাক্টিভিটি কলব্যাক ওভাররাইড করতে হবে না। যে কোড আপনার স্টেট ইনিশিয়ালাইজ ও সেভ করে, সেটি অ্যাক্টিভিটি ফিরে এলে সেটি নির্বিঘ্নে রিস্টোরও করে:

var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) {
    mutableStateOf(
        TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length))
    )
}

অ্যাক্টিভিটি ও নেভিগেশন

কোনও অ্যাপ তার লাইফটাইমে একাধিক স্ক্রিনের মধ্যে ট্রানজিশন করতে পারে, যেমন, ব্যবহারকারী ডিভাইসের 'ব্যাক' বোতামে ট্যাপ করলে অথবা নতুন ডেস্টিনেশন বেছে নিলে। আধুনিক Android অ্যাপ সাধারণত সিঙ্গেল-অ্যাক্টিভিটি আর্কিটেকচার ব্যবহার করে। প্রতিটি স্ক্রিনের জন্য নতুন Activity শুরু করার পরিবর্তে, আপনার অ্যাপ একটি সিঙ্গেল Activity হোস্ট করে এবং সেই অ্যাক্টিভিটির মধ্যে কম্পোজ করা যায় এমন স্ক্রিন অদল-বদল করতে Navigation কম্পোনেন্ট ব্যবহার করে।

আধুনিক, Compose-ফার্স্ট নেভিগেশন কীভাবে প্রয়োগ করতে হয় তা জানতে, Jetpack Compose Navigation 3 লাইব্রেরি সংক্রান্ত গাইড দেখুন।

একটি অ্যাক্টিভিটি থেকে অন্য একটি অ্যাক্টিভিটি শুরু করা

কোনও অ্যাক্টিভিটিকে কোনও এক সময় অন্য অ্যাক্টিভিটি শুরু করতে হতে পারে। যেমন, কোনও অ্যাপকে বর্তমান স্ক্রিন থেকে নতুন স্ক্রিনে সরানোর প্রয়োজন হলে এই প্রয়োজন দেখা দেয়।

আপনার অ্যাক্টিভিটি নতুন অ্যাক্টিভিটি থেকে কোনও ফলাফল চায় কিনা তার উপর নির্ভর করে এটি শুরু হতে চলেছে, আপনি startActivity পদ্ধতি বা startActivityForResult পদ্ধতি ব্যবহার করে নতুন অ্যাক্টিভিটি শুরু করেন। দুটি ক্ষেত্রেই, আপনাকে একটি Intent অবজেক্ট পাস করতে হবে।

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

startActivity

নতুন শুরু করা অ্যাক্টিভিটির ফলাফল ফেরত দেওয়ার প্রয়োজন না থাকলে, বর্তমান অ্যাক্টিভিটি startActivity মেথড কল করে এটি শুরু করতে পারে।

আপনার নিজের অ্যাপ্লিকেশনের মধ্যে কাজ করার সময়, আপনাকে প্রায়ই একটি পরিচিত অ্যাক্টিভিটি লঞ্চ করতে হয়। যেমন, নিম্নলিখিত কোড স্নিপেট থেকে কীভাবে SignInActivity নামের অ্যাক্টিভিটি লঞ্চ করতে হয় তা জানতে পারবেন।

val context = LocalContext.current

Button(onClick = {
    val intent = Intent(context, SignInActivity::class.java)
    context.startActivity(intent)
}) {
    Text("Sign In")
}

এক্সটার্নাল অ্যাক্টিভিটি শুরু করা

Navigation ইন্টার্নাল অ্যাপ নেভিগেশন ম্যানেজ করলেও, আপনার Activity-কে মাঝে মাঝে অন্যান্য অ্যাক্টিভিটি শুরু করতে হবে। সাধারণত, আপনি যখন কোনও নির্দিষ্ট অ্যাকশন পারফর্ম করার জন্য কোনও এক্সটার্নাল অ্যাপ ব্যবহার করতে চান, যেমন, ওয়েব ব্রাউজার খোলা, ইমেল পাঠানো বা ফটো তোলা, তখন এটি ঘটে।

এটি করতে, আপনি যে ধরনের অ্যাকশন পারফর্ম করতে চান তা বর্ণনা করতে একটি Intent অবজেক্ট ব্যবহার করেন এবং সিস্টেম অন্য অ্যাপ্লিকেশন থেকে উপযুক্ত অ্যাক্টিভিটি লঞ্চ করে।

যেমন, আপনি যদি ব্যবহারকারীকে ইমেল মেসেজ পাঠাতে দিতে চান, তাহলে আপনি নিম্নলিখিত ইনটেন্ট তৈরি করতে পারেন:

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

আপনাকে যদি কোনও এক্সটার্নাল অ্যাক্টিভিটি লঞ্চ করতে হয় এবং তার ফলাফল পেতে হয় (যেমন, ক্যামেরা অ্যাপকে ফটো তুলতে বলা এবং ইমেজ ফেরত পাওয়া), তাহলে পুরনো হয়ে যাওয়া startActivityForResult কলব্যাক ব্যবহার না করে আধুনিক Activity ফলাফল API ব্যবহার করুন।

অ্যাক্টিভিটি কোঅর্ডিনেট করা

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

লাইফসাইকেল কলব্যাকের ক্রম ভালভাবে সংজ্ঞায়িত করা হয়েছে, বিশেষ করে যখন দুটি অ্যাক্টিভিটি একই প্রসেসে থাকে—অন্য কথায়, একই অ্যাপ—এবং একটি অন্যটি শুরু করছে। অ্যাক্টিভিটি 'ক' থেকে অ্যাক্টিভিটি 'খ' শুরু হলে, এই ক্রমে অপারেশন হয়:

  1. Activity A-এর onPause মেথড এক্সিকিউট হয়।
  2. অ্যাক্টিভিটি B-এর onCreate, onStart ও onResume পদ্ধতি ক্রম অনুযায়ী এক্সিকিউট হয়। অ্যাক্টিভিটি 'খ'-এ এখন ব্যবহারকারীর ফোকাস আছে।
  3. স্ক্রিনে অ্যাক্টিভিটি 'ক' আর দেখা না গেলে, এর onStop মেথড এক্সিকিউট হয়।

লাইফসাইকেল কলব্যাকের এই ক্রম আপনাকে একটি অ্যাক্টিভিটি থেকে অন্য অ্যাক্টিভিটিতে তথ্য ম্যানেজ করতে দেয়।

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

অ্যাক্টিভিটি লাইফসাইকেল সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সম্পদ দেখুন:

কন্টেন্ট দেখা