android: when to use onStart(), onStop()? - android

I've read several posts that describe the difference between onStart() and onResume(): onStart() is called when the activity becomes visible, onResume() is called when the activity is ready for interaction from the user. fine.
I've always just added code to onPause() and onResume(), and never bothered with onStart() and onStop().
Can anyone give some concrete examples of what you might do in onStart(), vs. onResume()? Same goes for onStop() and onPause(), how is onStop() useful? I must be missing something fundamental here.

onStop() will (for example) be called when you leave the activity for some other activity (edit: almost. see commonswares comment about dialog themed activities).
For example if you use startActivity() in activity A to start activity B. When you press back in activity B you will return to activity A and onStart will be called.
This differs from some of the reasons onPause might be called without onStop being called. If for example the screen times out or you press the standy button onPause will be called, but probably not onStop (depending on memory available and whatnot), so it is a "lighter pause". onStop will be probably be called eventually even in this case, but not immediately.
Ok, but what's the use
Often there is no specific use, but there might be. Since your activities will keep its memory state on the stack even after you start some other activity, that stack will increase with the number of activities started (height of the stack).
This can lead to large memory usage in some applications. After a while the framework will kick in and kill some activities on the stack, but this is rather blunt and will probably mean a lot of states to be retained when returning.
So an example use for onStart/onStop is if you want to release some state when leaving an activity for another and recreate it when you get back.
I have used it to set listadapters to null, empty image caches and similar (in very specific applications). If you want to free the memory used by visible views in a listadapter you can recreate it in onstart and let the views be picked up by the gc. This will increase the likelyhood that the rest of the memory state of the activity will live on.
Some resources can be deemed good enough to save while the activity instance is alive and some only when it is on the front of the stack. It is up to you to decide what is best in your application and the granularity of create/start/resume gives you that.

onStart() works after onCreate() ended its task.
It's a good place to put a broadcastReceiver or initialize some state about the UI that should display consistently anytime the user comes back to this activity.
onResume() works when you come back to your Intent or Activity by pressing the back button. So onPause will be called every time a different activity comes to the foreground.

i think that your question is pretty explained here on the doc : read about the Activity Life Cycle

Related

What does "visibility" refer to in the Activity Lifecycle? onPause vs onStop?

The Activity Lifecycle is giving me headaches.
The documentation at http://developer.android.com/reference/android/app/Activity.html is so darn ambiguous when it describes the concept of visibility, that I can't figure out when onStop() is called vs onPause().
Compare the following two statements from the documentation:
(taken from right beneath the lifecycle diagram)
The onStart() and onStop() methods can be called multiple times, as
the activity becomes visible and hidden to the user.
vs
(further down in the blue table with the "killable" columns)
onPause() Called when the system is about to start resuming a previous activity.
What I'd understand from the first quote, is that onStop() is called on activity A when A is "hidden". "Hidden" I'd guess is referring to when another activity B has been resumed and is completely covering actvity A.
But the second quote then states that onPause() is called when another activity is about to start resuming. Wouldn't that completely hide activity A as well? Both cases seem to imply that that activity A becomes "hidden", no? According to my likely faulty interpretation, onPause() and onStop() are called in identical situations.
The documentation also seems to differ between being hidden (onStop() gets called) and being partial visibility (onPause() gets called). But when is an activity still partially visible? Do they mean literally? Or can an activity still be deemed "partially visible" when it has started up a new activity (activity calls startActivityForResult and starts a date picker activity) that covers the entire screen? Surely the activity is not going get onStop invoked? Its supposed to receive a result any moment!
So I'm trying to figure out what I'm not getting.
I understand that a call to onPause is guaranteed. That would be when activity A loses focus (device enters sleep mode, screenlock, etc), a different activity B takes the foreground (where activity B may or may not have been initiated by activity A).
But at which point is the onStop() invoked on activity A?
Is it matter of how many activities have been piled ontop of activity A on the activity stack? Are there two different definitions of "visiblity" at play?
Sorry about the wall of text, but I'm really frustrated :S
So the question stands: Precisely in which situations is an activity deemed "hidden" such that onStop() is called on it?
EDIT:
I inserted Toast notifications in each onX method, and discovered some additional weirdness:
Pressing the Home button will always call onStop(). But starting up the application won't call onRestart(). Instead it calls onCreate(). This seems strange to me, but ok...
When the "USB Mass Storage" activity is started on top of the main activity, onStop() is called. And when exiting the usb storage activity, returning to the main activity, onRestart() is called, instead of onCreate().
When the device goes into Sleep mode and is waken up, the activity only goes through the onPause() and onResume() cycle.
The last point was expected (although I can't get it to fit in the lifecycle diagram). But whats up with 1. and 2. ?
In the first point, I was expecting a call to onRestart() when starting the activity again. Why did it deallocate the activity and call onCreate() instead?
And take a look at point nr 2:
According to the documentation: when "another activity comes in front of the activity", onPaused() should be called. Isn't that what happened when the USB Storage activity came up? It didn't call onPause(), it went through the onStop() - OnRestart() cycle! Obviously, the documentation doesn't consider that a case where "another activity comes in front of the activity". So what really happened?
Ok, I think I've got this now.
1.
The key to the first point was this link:
http://code.google.com/p/android/issues/detail?id=2373
Its a bug. Theres some code in the link that has completely solved the problem with new root activity instances being created, instead of just restarting the last active activity (before the home button was pressed).
I put the code at the top of the onCreate method, just below the super.onCreate call:
if (!isTaskRoot()) {
final Intent intent = getIntent();
final String intentAction = intent.getAction();
if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
finish(); return;
}
}
Note that I added the return statement after finish so the rest of the onCreate method doesn't run in the case that the bug is detected.
2.& 3.
The key to the second and third points was these two links:
http://answers.oreilly.com/topic/2692-android-programming-understanding-the-activity-life-cycle/
How to make Activity, not covering full screen
It turns out that "visibility" really is literally! So when the documentation says "another activity comes in front of the activity", the activity behind the bumped activity is still partially visible. This means that the Android Activity manager must check whether the bumped Activity is a full-screen activity or not: If it is, onStop() is called on the previous activity. If not, then onPaused() is called on the previous activity instead.
This trivially explains why the USB Storage manager caused the onStop() to be called.
This also means that when device goes into sleep mode, the Activity Manager considers it a non-fullscreen activity, even though technically the main activity is completely hidden behind it.
(See the second link on how to make non-fullscreen activities )
Interestingly, the pull-down window (with the notifications) doesn't call onPause() (nor does it call onStop()), even though it would have made sense as a non-fullscreen activity. This must be some kind of exception that I'll be investigating on my own.
This also means that the onStop()-onRestart() cycle is probably more common than the onPause()-onResume() cycle (although both must still be accounted for), since activities probably more often than not are full-screen activities (personally, I thought the documentation indicated the opposite: that onPause-onResume was more commmon, but maybe thats just me).
Additionally, this must mean that when the main activity starts a new fullscreen activity for a result, the main activity will be first stopped and later restarted when the result-retrieveing activity is done.
So the only question now is how to best deal with a paused activity (meaning, it is covered by a non-fullscreen activity) that gets deallocated (although this case would be rare). What challenges may there be?
But thats outside the scope of this question.
Finally tracked this down: you can detect the status bar pulldown using onWindowFocusChanged()
how to use OnWindowFocusChanged method

Android onStop/onDestroy - when might these be used?

Looking at the Activity Life Cycle diagram, I notice that onPause() and onStop() can both lead to the "process" being killed. This would require onCreate() to be called when the user wants to resume their application. The point being that onStop() is not necessarily called, nor is onDestroy(), but that onPause() may be the only event that the Activity may see. This being the case, onPause() must handle saving the application status so that the user can return back to it later, regardless of whether onStop() is called or not.
I can see onDestroy() being used to clean up Activity specific resources that would naturally be eliminated in a process kill action. Is there anything else that onDestroy() would be good for?
And what would onStop() be good for? Why would I want to override it for?
If I got your question right: It depends what you want to do with your application. Let's say you are programming application that uses GPS. In the onStop() which is called when the activity is no longer visible to the user, you can remove these requests. Or you can stop the some service if your application is running any. Or you can save preferences (not recommended, do it in onPause() instead), or you can close permanent connection to a server.....If I think of anything else, I'll add more...
If you have read the doc further, you'll see following:
Saving activity state
The introduction to Managing the Activity Lifecycle briefly mentions
that when an activity is paused or stopped, the state of the activity
is retained. This is true because the Activity object is still held in
memory when it is paused or stopped—all information about its members
and current state is still alive. Thus, any changes the user made
within the activity are retained in memory, so that when the activity
returns to the foreground (when it "resumes"), those changes are still
there.
However, when the system destroys an activity in order to recover
memory, the Activity object is destroyed, so the system cannot simply
resume it with its state intact. Instead, the system must recreate the
Activity object if the user navigates back to it. Yet, the user is
unaware that the system destroyed the activity and recreated it and,
thus, probably expects the activity to be exactly as it was. In this
situation, you can ensure that important information about the
activity state is preserved by implementing an additional callback
method that allows you to save information about the state of your
activity and then restore it when the the system recreates the
activity.
Summary: After completing onStop() Activity object is still alive in memory. And this will help the system to restore the activity.
Very basic example: consider you are showing your activity to user, and suddenly your friend calls you! Rest you can understand..
So now it it up to you that, which are the resources/objects/connections should be released on which event.
Another example would be to register and unregister a broadcast receiver.
Note that usually these things are placed in onResume and onPause, the difference is subtle though, onResume/onPause are called when the activity gets placed behind another activity, onStart/onStop are called when the activity is no longer visible in the screen.

Why implement onDestroy() if it is not guaranteed to be called?

According to the android Activity Lifecycle, the only callback guaranteed to be called (if an activity ever leaves the Running state, which is typically expected) is onPause().
So, I must assume that there are scenarios in which it makes sense to implement onStop() and onDestroy() although they are not really guaranteed to be called.
I understand that onStop() should be implemented when it's possible for an activity to return to the Running state via the Stopped state (why would it do that instead of returning directly is a different question).
But the need for onDestroy(), when I can place all cleanup/state-saving into onPause(), is unclear to me.
Can you describe a real-app situation (i.e. not analogy to driving a car etc.) in which it would make sense to implement onDestroy()?
onDestroy will be called if you explicitly call finish(); yourself.
Your main activity calls startActivityForResult on a map activity.
Map activity with a LocationListener, the user clicks the map and selects say a local restaurant.
The activity then , sets up some extras to be sent back to your main activity, it then explicitly call's finish(); on itself and in the onDestroy kills the LocationListener and other variables you had invoked.
Just found this in the docs
onDestroy() = 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.
Can you describe a real-app situation
(i.e. not analogy to driving a car
etc.) in which it would make sense to
implement onDestroy()?
When you want to capture a configuration change. It's all in the SDK:
http://developer.android.com/reference/android/app/Activity.html

Interactivity Coordination: onStop and onResume

I have two activities. One loads all rows from a database, and the other saves to the database. When I have the second save in onStop and the first repull the data in onResume, they do it out of order (the first resumes and then the second saves). I managed to fix this by putting the saving data in onPause, but why was this happening? Was this the cleanest way to do it?
Doing the save in the first actvity's onPause should be fine.
You've discovered that the foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause(). During this time, the activity is in front of all other activities on screen and is interacting with the user.
When you start the second activity, onPause is called on the first and then interactive control switches to the second, with onStop on the first to be called somewhat in background.
This improves responsiveness and gets the new activity in front of the user ASAP. Consequently, you should try to keep your onPause implementation as fast and efficient as possible.
See the following Android docs for more details on the lifecycle http://developer.android.com/guide/topics/fundamentals.html, but what you have found should work fine for you.
Some official quote as an add-on:
The Activity documentation states that
onPause() is where you deal with the user leaving your activity.
Most importantly, any changes made by the user should at this point be
committed

Android - Notepad tutorial - lifecycle - some work done twice?

According to the "Application Fundamentals" article, section "component lifecycle", onResume() is always called when a View becomes active, independent of the previous state.
In the Notepad tutorial, Exercise 3, I have found something confusing in NoteEdit.java:
There is a call to populateFields() in onCreate() as well as in onResume().
Wouldn't it be enough (or even better) to have it only in onResume() ?
In such a small example, it will not do any harm if populateFields() is performed twice, but in a bigger App, things can be different ...
Thanks and Regards,
Markus N.
From a look at Notepad3, I would say you are correct. There doesn't seem to be any reason for them to call populateFields() in both onCreate() and onResume(). onResume is sufficient.
I can see where you need it in both places, if application pauses then you would need it in onResume and if your process gets killed or user navigates back to activity then you will need it in onCreate especially if you are doing some pre-processing.
Per the documentation....for onResume() they recommend using it for lightweight calls unlike in onCreate():
"The foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause(). During this time the activity is in front of all other activities and interacting with the user. An activity can frequently go between the resumed and paused states -- for example when the device goes to sleep, when an activity result is delivered, when a new intent is delivered -- so the code in these methods should be fairly lightweight. "
The Notepad app may want a variable declared if the method was already hit by onCreate not to redo in onResume().

Categories

Resources