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

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

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

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

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

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

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

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

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

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

চিত্র 1 এই দৃষ্টান্তের একটি চাক্ষুষ উপস্থাপনা উপস্থাপন করে।

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

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

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

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

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

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

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

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

onCreate()

আপনাকে অবশ্যই এই কলব্যাকটি বাস্তবায়ন করতে হবে, যেটি চালু হয় যখন সিস্টেমটি প্রথম কার্যকলাপ তৈরি করে। কার্যকলাপ সৃষ্টিতে, কার্যকলাপ তৈরি অবস্থায় প্রবেশ করে। onCreate() পদ্ধতিতে, বেসিক অ্যাপ্লিকেশন স্টার্টআপ লজিক সঞ্চালন করুন যা ক্রিয়াকলাপের পুরো জীবনের জন্য শুধুমাত্র একবার ঘটে।

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

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

onCreate() পদ্ধতির নিম্নলিখিত উদাহরণটি কার্যকলাপের জন্য মৌলিক সেটআপ দেখায়, যেমন ব্যবহারকারীর ইন্টারফেস ঘোষণা করা (একটি XML লেআউট ফাইলে সংজ্ঞায়িত করা), সদস্য ভেরিয়েবল সংজ্ঞায়িত করা এবং কিছু UI কনফিগার করা। এই উদাহরণে, XML লেআউট ফাইল ফাইলের রিসোর্স আইডি R.layout.main_activity কে setContentView() এ পাস করে।

কোটলিন

lateinit var textView: TextView

// Some transient state for the activity instance.
var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState)

    // Recover the instance state.
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity)

    // Initialize member TextView so it is available later.
    textView = findViewById(R.id.text_view)
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
override fun onSaveInstanceState(outState: Bundle?) {
    outState?.run {
        putString(GAME_STATE_KEY, gameState)
        putString(TEXT_VIEW_KEY, textView.text.toString())
    }
    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState)
}

জাভা

TextView textView;

// Some transient state for the activity instance.
String gameState;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState);

    // Recover the instance state.
    if (savedInstanceState != null) {
        gameState = savedInstanceState.getString(GAME_STATE_KEY);
    }

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity);

    // Initialize member TextView so it is available later.
    textView = (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putString(GAME_STATE_KEY, gameState);
    outState.putString(TEXT_VIEW_KEY, textView.getText());

    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState);
}

XML ফাইলটি সংজ্ঞায়িত করার এবং setContentView() এ পাস করার বিকল্প হিসাবে, আপনি আপনার কার্যকলাপ কোডে নতুন View অবজেক্ট তৈরি করতে পারেন এবং একটি ViewGroup নতুন View অবজেক্ট সন্নিবেশ করে একটি ভিউ হায়ারার্কি তৈরি করতে পারেন। তারপরে আপনি রুট ViewGroup setContentView() এ পাস করে সেই লেআউটটি ব্যবহার করুন। একটি ব্যবহারকারী ইন্টারফেস তৈরি সম্পর্কে আরও তথ্যের জন্য, ব্যবহারকারী ইন্টারফেস ডকুমেন্টেশন দেখুন।

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

অনস্টার্ট()

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

যখন ক্রিয়াকলাপটি সূচনা অবস্থায় চলে যায়, কার্যকলাপের জীবনচক্রের সাথে সংযুক্ত যেকোন জীবনচক্র-সচেতন উপাদান ON_START ইভেন্টটি গ্রহণ করে৷

onStart() পদ্ধতিটি দ্রুত সম্পন্ন হয় এবং তৈরি অবস্থার মতো, কার্যকলাপটি শুরু অবস্থায় থাকে না। একবার এই কলব্যাকটি শেষ হয়ে গেলে, কার্যকলাপটি পুনঃসূচনা অবস্থায় প্রবেশ করে এবং সিস্টেমটি onResume() পদ্ধতি চালু করে।

সারসংকলন()

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

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

যখন একটি বিঘ্নিত ঘটনা ঘটে, কার্যকলাপটি বিরাম দেওয়া অবস্থায় প্রবেশ করে এবং সিস্টেমটি onPause() কলব্যাকের আহ্বান জানায়।

যদি ক্রিয়াকলাপটি বিরতি দেওয়া অবস্থা থেকে পুনঃসূচনা অবস্থায় ফিরে আসে, সিস্টেমটি আবার onResume() পদ্ধতিতে কল করে। এই কারণে, onPause() এর সময় আপনি যে কম্পোনেন্টগুলি রিলিজ করেন তা শুরু করতে onResume() প্রয়োগ করুন এবং অন্য যেকোন ইনিশিয়ালাইজেশন সঞ্চালন করার জন্য যা প্রতিবার ক্রিয়াকলাপ পুনরায় শুরু হওয়া অবস্থায় প্রবেশ করতে হবে।

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

কোটলিন

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

জাভা

public class CameraComponent implements LifecycleObserver {

    ...

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void initializeCamera() {
        if (camera == null) {
            getCamera();
        }
    }
    ...
}

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

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

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

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

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

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

অনপজ()

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

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

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

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

আপনি সিস্টেম রিসোর্স, সেন্সর (যেমন জিপিএস) বা ব্যাটারি লাইফকে প্রভাবিত করে এমন কোনো রিসোর্স রিলিজ করতে 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
    }
    ...
}

জাভা

public class JavaCameraComponent implements LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void releaseCamera() {
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }
    ...
}

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

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

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

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

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

অনস্টপ()

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

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

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

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

কোটলিন

override fun onStop() {
    // Call the superclass method first.
    super.onStop()

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    val values = ContentValues().apply {
        put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
        put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
    }

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate(
            token,     // int token to correlate calls
            null,      // cookie, not used here
            uri,       // The URI for the note to update.
            values,    // The map of column names and new values to apply to them.
            null,      // No SELECT criteria are used.
            null       // No WHERE columns are used.
    )
}

জাভা

@Override
protected void onStop() {
    // Call the superclass method first.
    super.onStop();

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate (
            mToken,  // int token to correlate calls
            null,    // cookie, not used here
            uri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
    );
}

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

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

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

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

স্টপড স্টেট থেকে, অ্যাক্টিভিটি হয় ব্যবহারকারীর সাথে ইন্টারঅ্যাক্ট করতে ফিরে আসে, অথবা অ্যাক্টিভিটি শেষ হয়ে যায় এবং চলে যায়। যদি কার্যকলাপটি ফিরে আসে, তবে সিস্টেমটি 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 খালি করার প্রয়োজন হয় তখন সিস্টেমটি প্রক্রিয়াগুলিকে মেরে ফেলে। সিস্টেমের একটি প্রদত্ত প্রক্রিয়াকে হত্যা করার সম্ভাবনা সেই সময়ে প্রক্রিয়াটির অবস্থার উপর নির্ভর করে। প্রক্রিয়ার অবস্থা, ঘুরে, প্রক্রিয়ায় চলমান কার্যকলাপের অবস্থার উপর নির্ভর করে। সারণী 1 প্রক্রিয়া অবস্থা, কার্যকলাপ অবস্থা, এবং সিস্টেমের প্রক্রিয়াটিকে হত্যা করার সম্ভাবনার মধ্যে পারস্পরিক সম্পর্ক দেখায়। এই সারণীটি শুধুমাত্র তখনই প্রযোজ্য হয় যদি একটি প্রক্রিয়া অন্য ধরনের অ্যাপ্লিকেশন উপাদানগুলি চালায় না।

নিহত হওয়ার সম্ভাবনা প্রক্রিয়া অবস্থা চূড়ান্ত কার্যকলাপের অবস্থা
সর্বনিম্ন ফোরগ্রাউন্ড (ফোকাস পেতে বা পেতে) আবার শুরু হয়েছে
কম দৃশ্যমান (কোন ফোকাস নেই) শুরু/পজ করা হয়েছে
ঊর্ধ্বতন পটভূমি (অদৃশ্য) বন্ধ
সর্বোচ্চ খালি ধ্বংস হয়েছে

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

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

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

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

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

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

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

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

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

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

উদাহরণ রাষ্ট্র

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

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

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

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

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

দ্রষ্টব্য: অ্যান্ড্রয়েড সিস্টেম আপনার অ্যাক্টিভিটিতে ভিউয়ের অবস্থা পুনরুদ্ধার করতে, প্রতিটি ভিউয়ের একটি অনন্য আইডি থাকতে হবে, যা android:id অ্যাট্রিবিউট দ্বারা সরবরাহ করা হয়েছে।

একটি Bundle অবজেক্ট একটি তুচ্ছ পরিমাণ ডেটা সংরক্ষণের জন্য উপযুক্ত নয়, কারণ এটির জন্য প্রধান থ্রেডে সিরিয়ালাইজেশন প্রয়োজন এবং সিস্টেম-প্রসেস মেমরি ব্যবহার করে। খুব অল্প পরিমাণের বেশি ডেটা সংরক্ষণ করতে, স্থায়ী স্থানীয় সঞ্চয়স্থান, onSaveInstanceState() পদ্ধতি এবং ViewModel ক্লাস ব্যবহার করে ডেটা সংরক্ষণের জন্য একটি সম্মিলিত পদ্ধতি অবলম্বন করুন, যেমনটি সেভ UI স্টেটে বর্ণিত হয়েছে।

onSaveInstanceState() ব্যবহার করে সহজ, হালকা ওজনের UI অবস্থা সংরক্ষণ করুন

আপনার কার্যকলাপ বন্ধ হতে শুরু করলে, সিস্টেমটি onSaveInstanceState() পদ্ধতিতে কল করে যাতে আপনার কার্যকলাপ রাজ্যের তথ্য একটি ইনস্ট্যান্স স্টেট বান্ডেলে সংরক্ষণ করতে পারে। এই পদ্ধতির ডিফল্ট বাস্তবায়ন ক্রিয়াকলাপের ভিউ হায়ারার্কির অবস্থা সম্পর্কে ক্ষণস্থায়ী তথ্য সংরক্ষণ করে, যেমন একটি EditText উইজেটে পাঠ্য বা ListView উইজেটের স্ক্রোল অবস্থান।

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

কোটলিন

override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state.
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

জাভা

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state.
    savedInstanceState.putInt(STATE_SCORE, currentScore);
    savedInstanceState.putInt(STATE_LEVEL, currentLevel);

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(savedInstanceState);
}

দ্রষ্টব্য: onSaveInstanceState() বলা হয় না যখন ব্যবহারকারী স্পষ্টভাবে কার্যকলাপ বন্ধ করে বা অন্য ক্ষেত্রে যখন finish() কল করা হয়।

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

সংরক্ষিত উদাহরণ অবস্থা ব্যবহার করে কার্যকলাপ UI অবস্থা পুনরুদ্ধার করুন

আপনার কার্যকলাপ পূর্বে ধ্বংস হয়ে যাওয়ার পরে পুনরায় তৈরি করা হলে, আপনি Bundle থেকে আপনার সংরক্ষিত দৃষ্টান্তের অবস্থা পুনরুদ্ধার করতে পারেন যা সিস্টেমটি আপনার কার্যকলাপে পাস করে। onCreate() এবং onRestoreInstanceState() কলব্যাক পদ্ধতি উভয়ই একই Bundle পায় যাতে ইনস্ট্যান্স স্টেট তথ্য থাকে।

যেহেতু onCreate() পদ্ধতিটিকে বলা হয় সিস্টেমটি আপনার কার্যকলাপের একটি নতুন দৃষ্টান্ত তৈরি করছে বা আগেরটি পুনরায় তৈরি করছে, আপনি এটি পড়ার চেষ্টা করার আগে আপনাকে স্টেট Bundle শূন্য কিনা তা পরীক্ষা করতে হবে। যদি এটি শূন্য হয়, তবে সিস্টেমটি আগেরটি ধ্বংস হয়ে যাওয়া পুনরুদ্ধার করার পরিবর্তে কার্যকলাপের একটি নতুন উদাহরণ তৈরি করছে।

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে আপনি onCreate() এ কিছু স্টেট ডেটা পুনরুদ্ধার করতে পারেন:

কোটলিন

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        with(savedInstanceState) {
            // Restore value of members from saved state.
            currentScore = getInt(STATE_SCORE)
            currentLevel = getInt(STATE_LEVEL)
        }
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

জাভা

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        // Restore value of members from saved state.
        currentScore = savedInstanceState.getInt(STATE_SCORE);
        currentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

onCreate() এর সময় অবস্থা পুনরুদ্ধার করার পরিবর্তে, আপনি onRestoreInstanceState() প্রয়োগ করতে বেছে নিতে পারেন, যা onStart() পদ্ধতির পরে সিস্টেম কল করে। পুনরুদ্ধার করার জন্য একটি সংরক্ষিত অবস্থা থাকলেই সিস্টেমটি onRestoreInstanceState() কল করে, তাই আপনাকে Bundle শূন্য কিনা তা পরীক্ষা করার দরকার নেই।

কোটলিন

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState)

    // Restore state members from saved instance.
    savedInstanceState?.run {
        currentScore = getInt(STATE_SCORE)
        currentLevel = getInt(STATE_LEVEL)
    }
}

জাভা

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance.
    currentScore = savedInstanceState.getInt(STATE_SCORE);
    currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

সতর্কতা: সর্বদা onRestoreInstanceState() এর সুপারক্লাস বাস্তবায়নকে কল করুন যাতে ডিফল্ট বাস্তবায়ন ভিউ হায়ারার্কির অবস্থা পুনরুদ্ধার করতে পারে।

কার্যকলাপের মধ্যে নেভিগেটিং

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

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

একটি থেকে আরেকটি কার্যকলাপ শুরু করা

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

আপনার ক্রিয়াকলাপটি যে নতুন ক্রিয়াকলাপটি শুরু করতে চলেছে তার ফলাফল ফিরে চায় কিনা তার উপর নির্ভর করে, আপনি startActivity() পদ্ধতি বা startActivityForResult() পদ্ধতি ব্যবহার করে নতুন কার্যকলাপ শুরু করেন৷ উভয় ক্ষেত্রে, আপনি একটি Intent বস্তুতে পাস.

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

স্টার্ট অ্যাক্টিভিটি()

যদি নতুন শুরু করা কার্যকলাপের ফলাফল ফেরত দেওয়ার প্রয়োজন না হয়, তবে বর্তমান কার্যকলাপ startActivity() পদ্ধতিতে কল করে এটি শুরু করতে পারে।

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

কোটলিন

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

জাভা

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

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

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

কোটলিন

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

জাভা

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

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

startActivityForResult()

কখনও কখনও আপনি একটি কার্যকলাপ থেকে একটি ফলাফল ফিরে পেতে চান যখন এটি শেষ হয়. উদাহরণস্বরূপ, আপনি এমন একটি ক্রিয়াকলাপ শুরু করতে পারেন যা ব্যবহারকারীকে পরিচিতির তালিকা থেকে একজন ব্যক্তিকে বাছাই করতে দেয়৷ এটি শেষ হলে, এটি নির্বাচিত ব্যক্তিকে ফেরত দেয়। এটি করার জন্য, আপনি startActivityForResult(Intent, int) পদ্ধতিতে কল করুন, যেখানে পূর্ণসংখ্যা প্যারামিটার কলটি সনাক্ত করে।

এই শনাক্তকারীটি একই কার্যকলাপ থেকে startActivityForResult(Intent, int) একাধিক কলের মধ্যে পার্থক্য করার জন্য বোঝানো হয়েছে৷ এটি একটি বিশ্বব্যাপী শনাক্তকারী নয় এবং অন্যান্য অ্যাপ বা কার্যকলাপের সাথে বিরোধের ঝুঁকিতে নেই। ফলাফল আপনার onActivityResult(int, int, Intent) পদ্ধতির মাধ্যমে ফিরে আসে।

যখন একটি শিশু কার্যকলাপ প্রস্থান করে, তখন এটি তার পিতামাতার কাছে ডেটা ফেরত দিতে setResult(int) কল করতে পারে। চাইল্ড অ্যাক্টিভিটি অবশ্যই একটি ফলাফল কোড সরবরাহ করবে, যা মানক ফলাফল হতে পারে RESULT_CANCELED , RESULT_OK , বা RESULT_FIRST_USER থেকে শুরু হওয়া যেকোনো কাস্টম মান।

এছাড়াও, চাইল্ড অ্যাক্টিভিটি ঐচ্ছিকভাবে একটি Intent অবজেক্ট ফেরত দিতে পারে যাতে এটি চায় এমন কোনো অতিরিক্ত ডেটা থাকে। তথ্য প্রাপ্তির জন্য অভিভাবক কার্যকলাপ পূর্ণসংখ্যা শনাক্তকারীর সাথে প্রাথমিকভাবে সরবরাহ করা অভিভাবক কার্যকলাপ onActivityResult(int, int, Intent) পদ্ধতি ব্যবহার করে।

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

কোটলিন

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    // A contact was picked. Display it to the user.
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

জাভা

public class MyActivity extends Activity {
     // ...

     static final int PICK_CONTACT_REQUEST = 0;

     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             // When the user center presses, let them pick a contact.
             startActivityForResult(
                 new Intent(Intent.ACTION_PICK,
                 new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST);
            return true;
         }
         return false;
     }

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // A contact was picked. Display it to the user.
                 startActivity(new Intent(Intent.ACTION_VIEW, data));
             }
         }
     }
 }

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

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

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

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

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