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

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

অনপজ()

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

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

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

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

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

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

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

যখন আপনার কার্যকলাপ বন্ধ অবস্থায় প্রবেশ করে, তখন 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() এর মতো পূর্ববর্তী কলব্যাকগুলি দ্বারা প্রকাশিত সমস্ত সংস্থান প্রকাশ করে।

কার্যকলাপের অবস্থা এবং মেমরি থেকে ইজেকশন

সিস্টেমটি যখন র‌্যাম মুক্ত করার প্রয়োজন হয় তখন প্রক্রিয়াগুলি হত্যা করে। প্রদত্ত প্রক্রিয়াটি হত্যার সিস্টেমের সম্ভাবনা সেই সময় প্রক্রিয়াটির অবস্থার উপর নির্ভর করে। প্রক্রিয়া রাষ্ট্র, পরিবর্তে, প্রক্রিয়াটিতে চলমান ক্রিয়াকলাপের অবস্থার উপর নির্ভর করে। সারণী 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. ক্রিয়াকলাপ বি এর onCreate() , onStart() , এবং onResume() পদ্ধতিগুলি ক্রমানুসারে কার্যকর করে। ক্রিয়াকলাপ বিতে এখন ব্যবহারকারীর ফোকাস রয়েছে।
  3. যদি ক্রিয়াকলাপ এ আর স্ক্রিনে আর দৃশ্যমান না হয় তবে এর onStop() পদ্ধতিটি কার্যকর করে।

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