What Is the Correct Order of Calling Superclass Methods in Onpause, Onstop and Ondestroy Methods? and Why

What is the correct order of calling superclass methods in onPause, onStop and onDestroy methods? and Why?

Destroying the instance specific resources first, before destroying
superclass resources that the instance specific resources may depend
upon makes sense, not the other way round. But the comments suggest
otherwise. What am I missing?

In my opinion: not a single thing.

This answer from Mark (aka CommonsWare on SO) sheds light on the issue: Link - Should the call to the superclass method be the first statement?. But then, you can see the following comment left on his answer:

But why official doc says: "Always call the superclass method first" in onPause()?

Back to square one. Okay, let's look at this from another angle. We know that Java Language Specification does not specify an order in which the call to super.overridenMethod() must be placed (or if the call must be placed at all).

In case of class Activity, super.overridenMethod() calls are required and enforced:

if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}

mCalled is set to true in Activity.onStop().

Now, the only detail left to debate on is the ordering.

I also know that both work

Sure. Look at the method body for Activity.onPause():

protected void onPause() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);

// This is to invoke
// Application.ActivityLifecyleCallbacks.onActivityPaused(Activity)
getApplication().dispatchActivityPaused(this);

// The flag to enforce calling of this method
mCalled = true;
}

Whichever way you sandwich the call to super.onPause(), you'll be ok. Activity.onStop() has a similar method body. But take a look at Activity.onDestroy():

protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;

// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}

// close any cursors we are managing.
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}

// Close any open search dialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}

getApplication().dispatchActivityDestroyed(this);
}

Here, the ordering could possibly matter depending on how your activity is setup, and whether calling super.onDestroy() would interfere with the code that follows.

As a final word, the statement Always call the superclass method first doesn't seem to have much evidence to back it up. What's worse (for the statement) is that the following code has been taken from android.app.ListActivity:

public class ListActivity extends Activity {

....

@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
....
}

And, from LunarLander sample application included in android sdk:

public class LunarLander extends Activity {

....

@Override
protected void onPause() {
mLunarView.getThread().pause(); // pause game when Activity pauses
super.onPause();
}
....
}

Summary and worthy mentions:

User Philip Sheard : Provides a scenario where a call to super.onPause() must be delayed in case of an Activity started using startActivityForResult(Intent). Setting the result using setResult(...) after super.onPause() will not work. He later clarifies on this in the comments to his answer.

User Sherif elKhatib : Explains why letting superclass initialize its resources first and destroy its resources last follows from logic:

Let us consider a library you downloaded which has a LocationActivity
that contains a getLocation() function that provides the location.
Most probably, this activity will need to initialize its stuff in the
onCreate() which will force you to call the super.onCreate first
. You
already do that because you feel it makes sense. Now, in your
onDestroy, you decide you want to save the Location somewhere in the
SharedPreferences. If you call super.onDestroy first, it is to a
certain extent possible that getLocation will return a null value
after this call because the implementation of LocationActivity
nullifies the location value in the onDestroy. The idea is that you
wouldn't blame it if this happens. Therefore, you would call
super.onDestroy at the end after you're done with your own onDestroy.

He goes on to point out: if a child class is suitably isolated (in terms of resource dependency) from the parent class, the super.X() calls need not adhere to any order specification.

See his answer on this page to read through a scenario where placement of super.onDestroy() call does affect the program logic.

From an answer by Mark:

Methods you override that are part of component creation (onCreate(),
onStart(), onResume(), etc.), you should chain to the superclass as
the first statement
, to ensure that Android has its chance to do its
work before you attempt to do something that relies upon that work
having been done.

Methods you override that are part of component
destruction (onPause(), onStop(), onDestroy(), etc.), you should do
your work first and chain to the superclass as the last thing
. That
way, in case Android cleans up something that your work depends upon,
you will have done your work first.

Methods that return something
other than void (onCreateOptionsMenu(), etc.), sometimes you chain to
the superclass in the return statement, assuming that you are not
specifically doing something that needs to force a particular return
value.

Everything else -- such as onActivityResult() -- is up to you,
on the whole. I tend to chain to the superclass as the first thing,
but unless you are running into problems, chaining later should be
fine.

Bob Kerns from this thread:

It's a good pattern [(the pattern that Mark suggests above)], but I've found some exceptions. For example,
the theme I wanted to apply to my PreferenceActivity wouldn't take
effect unless I put it before the superclass's onCreate().

User Steve Benett also brings attention to this:

I only know one situation, where the timing of the super call is
necessary. If you wanna alter the standard behavior of the theme or
the display and such in onCreate, you have to do it before you call
super to see an effect
. Otherwise AFAIK there is no difference at
which time you call it.

User Sunil Mishra confirms that order (most likely) does not play a role when calling Activity class' methods. He also claims that calling superclass methods first is considered a best practice. However, I could not corroborate this.

User LOG_TAG : Explains why a call to superclass constructor needs to be the before everything else. In my opinion, this explanation does not add to the question being asked.

End note: Trust, but verify. Most of the answers on this page follow this approach to see if the statement Always call the superclass method first has logical backing. As it turns out, it does not; at least, not in the case of class Activity . Generally, one should read through the superclass' source code to determine if ordering calls to super's methods is a requirement.

Android: Call super() at the beginning or end of onStart(), onStop(), onDestroy() in activity?

That's my way of calling these super methods:

  • OnCreate(): Definitely the first thing.
  • OnDestroy(): The last thing.
  • OnStop(): The last thing.

However, for the last two, no matter where you call them (in most most cases). So some people prefer to put them at the first to be consistent.

Android implementation of lifecycle methods can call the superclass implementation after doing any work?

Directly copied from CommonsWare's this answer. So better give him the upvote

Methods you override that are part of component creation
(onCreate(), onStart(), onResume(), etc.), you should chain to
the superclass as the first statement, to ensure that Android has its
chance to do its work before you attempt to do something that relies
upon that work having been done.

Methods you override that are part of component destruction
(onPause(), onStop(), onDestroy(), etc.), you should do your
work first and chain to the superclass as the last thing. That way, in
case Android cleans up something that your work depends upon, you will
have done your work first.

Methods that return something other than void
(onCreateOptionsMenu(), etc.), sometimes you chain to the superclass
in the return statement, assuming that you are not specifically doing
something that needs to force a particular return value.

Everything else -- such as onActivityResult() -- is up to you, on
the whole. I tend to chain to the superclass as the first thing, but
unless you are running into problems, chaining later should be fine.

But if there is no dependancy, then call the superclass methods anywhere you want.

Android - While switching between two activities, the calling order of lifecycle methods of Activity

According to the documentation, SECOND.onResume() is supposed to be called before FIRST.onStop()
https://developer.android.com/guide/components/activities/activity-lifecycle#coordinating-activities
(Coordinating activities section)

Should the call to the superclass method be the first statement?

Methods you override that are part of component creation (onCreate(), onStart(), onResume(), etc.), you should chain to the superclass as the first statement, to ensure that Android has its chance to do its work before you attempt to do something that relies upon that work having been done.

Methods you override that are part of component destruction (onPause(), onStop(), onDestroy(), etc.), you should do your work first and chain to the superclass as the last thing. That way, in case Android cleans up something that your work depends upon, you will have done your work first.

Methods that return something other than void (onCreateOptionsMenu(), etc.), sometimes you chain to the superclass in the return statement, assuming that you are not specifically doing something that needs to force a particular return value.

Everything else -- such as onActivityResult() -- is up to you, on the whole. I tend to chain to the superclass as the first thing, but unless you are running into problems, chaining later should be fine.

Why onDestroy called when returning to parent activity in PAD?

Please take a look at the diagram in the following link. http://developer.android.com/reference/android/app/Activity.html when you you call on finish() it will call on destroy after that call since you are done with the activity .

System call onPause and onStop

To keep it simple, here is the small info from the android developers documentation.

Activity Lifecycle

Activities in the system are managed as an activity stack. When a new activity is
started, it is placed on the top of the stack and becomes the running activity --
the previous activity always remains below it in the stack, and will not come to the
foreground again until the new activity exits.

An activity has essentially four states:

If an activity in the foreground of the screen (at the top of the stack), it is active or running.
If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

Please refer to this life cycle demo application. It's really helpful in understanding the Activity lifecycle.

Also as Raghunandan suggested, you must read this.

Added:

For instance: When a user traverses from Activity A to Activity B (FullScreen Non Transparent) following things happens

  1. Activity A's state changes to paused state (which calls onPause on Activity A)
  2. Then Activity A's state changes from paused to stopped state (which calls
    onStop on Activity A) . onStop is called because Activity B was full screen
    non transparent activity.
    (If Activity B is non-full-sized or transparent then onStop is NOT called on Activity A)

onPause is guaranteed to be called on Activity A (No matter whether Activity B is non-full-sized transparent or full-sized). onStop will only be called when Activity A is completely overridden by full-sized Activity B.

So in onPause you can save an Activity's state or some other useful info if required.

Good Luck :)



Related Topics



Leave a reply



Submit