As per Android activity life cycle, when activity is no longer visible onStop will get called. But this is not happening, if i exit the second activity quickly.
I have two activities HomeActivity and DetailActivity.
Step 1. Pressing a button on HomeActivity navigates to DetailActivity
Step 2. Back press on DetailActivity navigates to HomeActivity
When navigates to DetailActivity , the onStop of HomeActivity should get called as per activity life cycle, since the DetailActivity gets onStart.
But onStop is not getting called if i back press on DetailActivity quickly.
Activity life cycle if back pressed immediately..
HomeActivity: onPause
DetailActivity: onStart
DetailActivity: onResume
DetailActivity: onPostResume
DetailActivity: onPause
HomeActivity: onResume
HomeActivity: onPostResume
DetailActivity: onStop
Activity life cycle if back pressed after a delay (say few seconds later on DetailActivity)
HomeActivity: onPause
DetailActivity: onStart
DetailActivity: onResume
DetailActivity: onPostResume
HomeActivity: onStop
DetailActivity: onPause
HomeActivity: onStart
HomeActivity: onResume
HomeActivity: onPostResume
DetailActivity: onStop
Doesn't this look like a bug as new Activity is Started, the previous activity is not stopped?
According to Android Docs about stopping and restart of an Activity
The user performs an action in your app that starts a new activity. The current activity is stopped when the second activity is created. If the user then presses the Back button, the first activity is restarted.
They should update it to say If the user the presses the Back button but not to quickly haha, but I think iheanyi is right in the fact that some other process may have been granted cpu time after the DetailsActivity hit onPostResume and the back button was pressed before the OS could continue with the onStop process of the HomeAcitvity
You've described normal behavior. Here's what https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle says about this:
Called when the activity is no longer visible to the user, because
another activity has been resumed and is covering this one. This may
happen either because a new activity is being started, an existing one
is being brought in front of this one, or this one is being destroyed.
Followed by either onRestart() if this activity is coming back to
interact with the user, or onDestroy() if this activity is going away.
So, you may be wondering, well, if my new activity is visible, doesn't that mean the previous activity is invisible? Not really. Your new activity may not completely overlap the old one (in which case, part of the old is still visible). This could be especially tricky if the old activity has elements that while "invisible" to the user because they look the same as elements from the new activity, are technically still visible (in that they're not completely blocked by the new).
Visibility aside, you could also inadvertently have lifecycle methods timing issues which lead to this. Let's say your onPause() takes a long time to complete. The other activity could completely hide the old, satisfying the conditions for onStop(), but you transition back before onStop() has a chance to run.
Finally, there are many tasks that need to run on the phone and few processors to execute them. Necessarily, some tasks will have higher priority than others. Think about the code that must execute when your new activity is taking over the foreground - there is no way that onStop() has time to run if the phone is busy executing code for your activity. If that code then triggers onResume, onStop would be skipped altogether.
As you can see from the life cycle diagram, you can transition from onPause() back to onResume() without going through onStop(). Perhaps you should think about the scenarios where something like that can happen (and why) to better understand your particular case.
Related
I just read the following from Android Developers docs:
Here's the order of operations that occur when Activity A starts
Activity B:
Activity A's onPause() method executes.
Activity B's onCreate(), onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)
Then, if Activity A is no longer visible on screen,
its onStop() method executes.
I just want to know when an activity can start another and still be visible(a concrete example). (because it means that onStop() is always calls when I switch activities)
You can start an Activity B like a dialog if you specify a flag in AndroidManifest.xml:
<activity android:name=".ActivityB"
android:theme="#android:style/Theme.Holo.Light.Dialog"/>
Then Activity B will not take the full screen and you will still see the underlying activity.
onStop() won't be called if you previous activity is visible to user.
onStop will be called only after previous activity is completely invisible to user.
So if new activity is dialog or some transparent background, then previous activity will be displayed to user and onStop() of previous activity won't be called.
In the Android developer diagram, I saw that onResume() is always called before onPause(). Assuming the user starts a new Activity, why should onPause() be preceded by onResume()?
I mean:
OnResume can be called in 2 occassions:
1) when user starting new activity (before OnPause)
2) when activity is in background and if the user brings the activity back to the
foreground
I expect in every case, something else should be done.
You are getting it wrong. Whenever an activity is created, onResume is called just after onStart. Whenever your activity goes back stack onPause is called. Again if your activity comes back to foreground then onResume is called. So, it is not like, onResume is called before onPause. Whenever activity is returning from onPause state, onResume gets called instead of onStart or onCreate. This happens so that Android does not have to create Activity instance again and again though those instances are not properly destroyed. This is quite memory efficient too.
NOTE: If you app is running and the user presses back button or home button, then the Activity goes through onPause() and onStop() state. After this if the user is again coming back to your app then, onRestart(), onStart() and onResume() will be called sequentially.
Then when the activity is only in onPause() state ? When a dialog surfaces on top of your activity or your activity is getting displayed in Split screen but it doesn't have focus (user is not interacting with your app). On these cases, activity goes to onPause() state only.
onResume() is always called before onPause()
This is correct. onResume is always called when the Activity is launched for the first time, before onCreate, and when the Activity is being resumed (user navigates back to your Activity)
Assuming the user starts a new Activity, why should onPause() be
preceded by onResume()
onPause is only called when the Activity is put to background, or before onDestroy if the Application is being destroyed. So onPause is always being called after a call to onResume has been made. Why? Because that's the lifecycle of the Activity as defined by the Android framework.
The life cycle of the activity is as follows
Fresh start via onCreate(), onStart(), onResume .... and close via onPause()->onStop()->onDestroy()
Yellow background: Activity goes into background and thus is no longer visible. The user returns back to the activity.
e.g.
Switch off the phone screen while the activity is running: onPause()->onStop()
Switch on the screen again: onStart() -> onResume()
Green background: The activity stays in the visible screen area but is not active
e.g. Activate multiple windows (split screen) occupying one part of the screen each and tip on your app to make it active
tip on the other app: onPause() is called in your app as it goes into pause but is still visible
tip on your app: onResume() is called
Here is an example of a split screen with two apps:
see android documentation on activity life cycle for details
I am making a demo to understand back stack and activity life-cycle.
I made:
MainActivity
MainActivityDialog (another activity theme as dialog)
BActivity
I launched this app and Main Activity is shown. Then press a button to show the dialog, then MainActivityDialog is opened. Then I again press button on MainActivityDialog then BActivity is opened. Finally, I pressed the back button.
MainActivity -> MainActivityDialog -> BActivity ---Back---> MainActivityDialog
Here is the log of this app :
My question are:
Why MainActivity get stopped after launching BActivity from MainActivityDialog? Then after BActivity lifecycle method is called, why MainActivityDialog get stopped?
After pressing back button in BActivity, MainActivity starts first then MainActivityDialog starts and then MainActivityDialog resume?
The order of calls to onStop() and onDestroy() on multiple activities is indeterminate.
If you have multiple activities in your activity stack that are no longer visible on screen, Android may call onStop() on them whenever it wants to and in whatever order it wants to. This is only an indication to the activity that it is no longer visible to the user. You cannot rely on the order of onStop() calls to multiple activities.
The same goes for onDestroy(). Android may call onDestroy() on an activity once that activity has finished. If you have multiple finished activities in your task, Android may call onDestroy() on them whenever it wants to and in whatever order it wants to. This is also indeterminate. The call to onDestroy() is just to inform the activity that it is no longer active and that it should release any resources it may have.
There is no guarantee that onStop() or onDestroy() will ever be called. The last lifecycle call that is guaranteed is onPause(). After that, Android can just kill the process without calling any further lifecycle methods.
In your second question you want to know why, after the user presses the BACK button on BActivity, MainActivity starts first followed by MainActivityDialog. The reason is that MainActivity is visible on screen FIRST and then MainActivityDialog is visible on screen on top of MainActivity (because MainActivityDialog is Dialog-themed, it doesn't cover the entire screen and you can see parts of MainActivity underneath it).
Im not a pro at Android, but since nobody has answered yet, i will try my best. I want to help because i also learn android by doing something like you did (using log cat to see activiti's current state) for the first time.
Why MainActivity get stopped after launching BActivity from
MainActivityDialog?
Every time you start a new activity, the old activity will always be paused/stopped.
Then after BActivity lifecycle method is called, why
MainActivityDialog get stopped?
Because now the current active activity is BActivity, in other word : MainActivityDialog is not active/visible hence its stopped/paused.
After pressing back button in BActivity, MainActivity starts first
then MainActivityDialog starts and then MainActivityDialog resume?
Yes, because you started MainActivityDialog from MainActivity, so MainActivity will be restarted first.
Please feel free to comment, im also still learning :)
I am little confused between the life cycle of two activities.
Suppose I have Activity A and Activity B.
B is called From A i.e A ----> B.
Now currently B is on the screen and I pressed back button. Here I want know:- is there any memory still available for B(Active) or B's memory is flushed(Inactive).
The following activity call back methods are called, after pressing back button.
onPause()
onStop()
onDestroy()
The activity is destroyed.
And it recreates when launched again. These are the callback methods when it launches again.
onCreate()
onStart()
onResume()
I know the answer is been accepcted, still if this helps someone I am putting it.
When app is opening for the first time, by clicking the Icon
onCreate()
onStart()
onResume()
When home button is pressed
onPause()
onStop()
when app is again opened by clicking the app icon or launched from recent
onRestart()
onStart()
onResume()
when app is opened and then back button is pressed
onPause()
onStop()
onDestroy()
The onDestroy method is called after back press. Then activity will be popped from the Activity back stack.
From docs:
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.
onDestroy() from docs:
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
Activity B will be destroyed and will no longer remain in memory.
For more information please visit the official documentation for android and have a look at the activity life cycle figure.
Once you press the back key the activity's onDestroy() method will be called and the activity will be flushed out of the memory. You will then be required to restart the activity by calling the startActivity() method which will in turn call its onCreate() Method.
I would suggest to refer following link for activity lifecycle
http://stackoverflow.com/a/8516056/3110609
and following link for launch mode of activity.
www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
After pressing the back button, Activity B will b destroyed. You see, Android Manages Activities like a Stack(an explanation of a stack). Everytime you start an activity, it pushes into the Activity Stack. So when Activity A calls Activity B, Activity B is now on top of Activity B, and when you press the back button, it also does a pop in the Activity Stack. So in concept, Activity B is gone. Pressing a Home Button is different from pressing back, it pauses the Activity, therefore it still eats a little of the phone's memory.
Here is a good explanation of how Android Manages Activities.
You're on an activity and you press the home button.
Then you long press home menu button, and select the activity you were on, from the 'recent activities' screen.
What method is called when the activity shows again? onResume, onRestart or any other?
I believe onResume will be called anyways even after pause or stopped.
onRestart may be called if activity has been stopped in the background
The recommendation is to save your data in onPause and rebuild it on onResume with some flags, so flags can tell you if onResume called after onPause/onStopped or Activity is freshly created.
Taken from the Android developer website
"... When the user leaves your activity, the system calls onStop() to stop
the activity (1). If the user returns while the activity is stopped,
the system calls onRestart() (2), quickly followed by onStart() (3)
and onResume() (4). Notice that no matter what scenario causes the
activity to stop, the system always calls onPause() before calling
onStop()..."
Here is the Activity
So no Matter what onResume() would get eventually called.
You can download the ActivityDemo which exhibits the Android lifecycle accurately. This should help you.