2

I am new to android programming and would like to make clear the concept of Activity Lifecycle.

To make it simple, I have shortened the case as below:

  • There are 2 activities (MainActivity and Main2Activity).

  • In MainActivity, a button is created to open Main2Activity.

  • In Main2Activity, in order to simulate user returning to MainActivity once Main2Activity is shown, it calls finish() and return to MainActivity in onCreate().

When the button is clicked, I found that there seems to have race condition occurred.

  • MainActivity::onCreate() <-- 1st MainActivity instance
  • MainActivity::onStart() <-- 1st MainActivity instance
  • MainActivity::onResume() <-- 1st MainActivity instance
  • MainActivity::onPause() <-- 1st MainActivity instance
  • MainActivity::onCreate() <-- 2nd MainActivity instance
  • MainActivity::onStart() <-- 2nd MainActivity instance
  • MainActivity::onResume() <-- 2nd MainActivity instance
  • MainActivity::onStop() <-- 1st MainActivity instance
  • MainActivity::onDestroy() <-- 1st MainActivity instance

The last onDestory() from the 1st MainActivity instance will run after the onCreate(), onStart(), onResume() from the 2nd MainActivity instance.

How can I ensure the onDestroy() is called before starting another activity?

Thanks very much for everyone's help.


MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button btnClick = findViewById(R.id.btnClick);
    btnClick.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // finish self
            finish();
            // start Main2Activity
            Intent intent = new Intent(v.getContext(), Main2Activity.class);
            startActivity(intent);
        }
    });
}

Main2Activity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    // return to MainActivity
    Intent intent = new Intent(this, MainActivity.class);
    startActivity(intent);
    // finish self
    finish();
}
hkckfs340
  • 23
  • 2
  • nice question ! – iamkdblue Aug 27 '18 at 17:30
  • Why do you think this is a problem? (AFAIK you can't do much about it, the runtime finishes/destroys Activities at its own pace. It depends on the Android version and the hardware as well as other factors like how many other apps are currently requesting resources) – Bö macht Blau Aug 27 '18 at 18:33
  • What I plan is to release resources when the activity is destroyed. If the onDestroy() is not guaranteed to be called before a new instance of the same activity is created, it will accidentally release singleton resources being using by another instance. – hkckfs340 Aug 28 '18 at 04:12

2 Answers2

0

Not sure its the solution but give it a try..

on Main2Activity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main2);

// return to MainActivity

new Handler().postDelayed(new Runnable() {

     @Override
     public void run() {
       Intent intent = new Intent(this, MainActivity.class);    
       startActivity(intent);
     }
},5000);

// finish self
finish();
}

this would call the startActivity after 5 seconds .. that would give for the finish enough time to call all the life cycle

Itzik Samara
  • 2,278
  • 1
  • 14
  • 18
-1

You can call isFinishing() on your first MainActivity instance.

Here is the documentation for this method.

This would look like :

if (isFinishing()) {
  //onDestroy() has not been called yet
}
else {
  //onDestroy() has been called already
}
ArcDexx
  • 453
  • 5
  • 15
  • no, this is not what `isFinishing()` is checking. Read the docs you linked to. – Marcin Orlowski Aug 27 '18 at 17:35
  • Thanks. I will try this approach to check the isFinishing() value in onPause() and to release resources if true. – hkckfs340 Aug 27 '18 at 17:42
  • @MarcinOrlowski `finish()` is explicitly called here. A call to this method will eventually trigger `onDestroy()`. See this answer for details : https://stackoverflow.com/questions/19891969/android-will-finish-always-call-ondestroy – ArcDexx Aug 29 '18 at 13:31
  • `isFinishing()` is in no way telling if `onDestroy()` was called as your comments suggest. In fact if it was, then your instance is already dead. – Marcin Orlowski Aug 29 '18 at 13:53