কার্যকলাপ জীবনচক্র

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

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

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

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

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

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

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

কার্যকলাপ-জীবনচক্র ধারণা

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

চিত্র ১-এ এই প্রতিমানটির একটি চাক্ষুষ উপস্থাপনা তুলে ধরা হয়েছে।

চিত্র ১. কার্যকলাপ জীবনচক্রের একটি সরলীকৃত চিত্র।

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

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

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

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

রচনা এবং জীবনচক্র

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

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

Compose এবং এর জীবনচক্র সম্পর্কে আরও জানতে, Jetpack Compose-এর জীবনচক্র দেখুন।

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

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

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

onCreate

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

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

আপনার যদি একটি লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্ট থাকে যা আপনার অ্যাক্টিভিটির লাইফসাইকেলের সাথে সংযুক্ত, তবে এটি 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!")
}

আপনার অ্যাক্টিভিটি Created অবস্থায় থাকে না। onCreate মেথডটির এক্সিকিউশন শেষ হওয়ার পর, অ্যাক্টিভিটিটি Started অবস্থায় প্রবেশ করে এবং সিস্টেম দ্রুত পরপর onStartonResume মেথডগুলোকে কল করে।

শুরুতে

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

যখন অ্যাক্টিভিটিটি Started অবস্থায় চলে যায়, তখন অ্যাক্টিভিটির লাইফসাইকেলের সাথে যুক্ত যেকোনো লাইফসাইকেল-সচেতন কম্পোনেন্ট ON_START ইভেন্টটি গ্রহণ করে।

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

রিজুমে

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

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

যখন কোনো বিঘ্নকারী ঘটনা ঘটে, তখন অ্যাক্টিভিটিটি Paused অবস্থায় প্রবেশ করে এবং সিস্টেম onPause কলব্যাকটি চালু করে।

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

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

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

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

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

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

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

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

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

বিরতিতে

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

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

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

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

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

তবে, onResume সম্পর্কিত অংশে যেমন উল্লেখ করা হয়েছে, অ্যাপটি মাল্টি-উইন্ডো মোডে থাকলে একটি Paused অ্যাক্টিভিটি তখনও সম্পূর্ণরূপে দৃশ্যমান থাকতে পারে। মাল্টি-উইন্ডো মোডকে আরও ভালোভাবে সাপোর্ট করার জন্য 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 ব্যবহার করবেন না । এই ধরনের কাজ মেথডটি শেষ হওয়ার আগেই হয়তো সম্পূর্ণ নাও হতে পারে।

Instead, perform heavy-load shutdown operations during onStop . For more information about suitable operations to perform during onStop , see the next section. For more information about saving data, see the section about saving and restoring state .

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

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

অনস্টপ

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

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

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

এছাড়াও, তুলনামূলকভাবে সিপিইউ-এর উপর বেশি চাপ সৃষ্টিকারী শাটডাউন অপারেশনগুলো সম্পাদন করতে 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()
}

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

From the Stopped state, the activity either comes back to interact with the user, or the activity is finished running and goes away. If the activity comes back, the system invokes onRestart . If the Activity is finished running, the system calls onDestroy .

ধ্বংস করুন

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

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

When the activity moves to the destroyed state, any lifecycle-aware component tied to the activity's lifecycle receives the ON_DESTROY event. This is where the lifecycle components can clean up anything they need to before the Activity is destroyed.

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

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

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

onDestroy কলব্যাকটি onStop মতো পূর্ববর্তী কলব্যাক দ্বারা মুক্ত না হওয়া সমস্ত রিসোর্স মুক্ত করে।

কার্যকলাপের অবস্থা এবং স্মৃতি থেকে বহিষ্কার

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

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

প্রক্রিয়া অবস্থা

চূড়ান্ত কার্যকলাপের অবস্থা

সর্বনিম্ন

সম্মুখভাগ (যেখানে ফোকাস আছে বা ফোকাস আসতে চলেছে)

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

নিম্ন

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

শুরু/বিরতি

উচ্চতর

পটভূমি (অদৃশ্য)

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

সর্বোচ্চ

খালি

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

সারণি ১. প্রক্রিয়া জীবনচক্র এবং কার্যকলাপের অবস্থার মধ্যে সম্পর্ক।

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

ব্যবহারকারী সেটিংস-এর অধীনে থাকা অ্যাপ্লিকেশন ম্যানেজার ব্যবহার করেও সংশ্লিষ্ট অ্যাপটি বন্ধ করতে পারেন।

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

অস্থায়ী UI অবস্থা সংরক্ষণ এবং পুনরুদ্ধার করা

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

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

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

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

ইনস্ট্যান্স অবস্থা

এমন কয়েকটি পরিস্থিতি রয়েছে যেখানে অ্যাপের স্বাভাবিক আচরণের কারণে আপনার অ্যাক্টিভিটি ধ্বংস হয়ে যায়, যেমন যখন ব্যবহারকারী ব্যাক বাটন চাপেন অথবা আপনার অ্যাক্টিভিটি finish মেথড কল করার মাধ্যমে নিজের ধ্বংসের সংকেত দেয়।

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

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

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

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

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

খুব অল্প পরিমাণের চেয়ে বেশি ডেটা সংরক্ষণ করতে, "Save UI states" অংশে বর্ণিত পদ্ধতি অনুযায়ী পারসিস্টেন্ট লোকাল স্টোরেজ, ViewModel ক্লাস এবং Compose স্টেট হোয়েস্টিং ব্যবহার করে একটি সমন্বিত পদ্ধতি অবলম্বন করুন।

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))
    )
}

কার্যকলাপ এবং নেভিগেশন

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

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

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

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

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

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

কার্যকলাপ শুরু করুন

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

আপনার নিজের অ্যাপ্লিকেশনে কাজ করার সময়, প্রায়শই একটি পরিচিত অ্যাক্টিভিটি চালু করার প্রয়োজন হয়। উদাহরণস্বরূপ, নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে SignInActivity নামক একটি অ্যাক্টিভিটি চালু করতে হয়।

val context = LocalContext.current

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

বাহ্যিক কার্যক্রম শুরু করা

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

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

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

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

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

সমন্বয়মূলক কার্যক্রম

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

লাইফসাইকেল কলব্যাকগুলোর ক্রম সুনির্দিষ্ট, বিশেষ করে যখন দুটি অ্যাক্টিভিটি একই প্রসেসে—অর্থাৎ একই অ্যাপে—থাকে এবং একটি অন্যটিকে চালু করে। অ্যাক্টিভিটি A যখন অ্যাক্টিভিটি B চালু করে, তখন যে অপারেশনগুলো ঘটে তার ক্রম নিচে দেওয়া হলো:

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

লাইফসাইকেল কলব্যাকগুলির এই ক্রম আপনাকে একটি অ্যাক্টিভিটি থেকে অন্য অ্যাক্টিভিটিতে তথ্যের স্থানান্তর পরিচালনা করতে সাহায্য করে।

অতিরিক্ত সম্পদ

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

বিষয়বস্তু দেখুন