Hi All!
I have an Activity which allocates quite lot of memory while it shows a visible layout. The UI heavily depends on this memory, however, there is no need to keep these allocations after the user traverses away from the Activity (usually by bringing another Activity to focus).
The Activity starts to allocate memory in onResume() and all is fine with that. It's the deallocation that confuses me a bit, though. As of now I release all memory in onPause() which also destroys the corresponding UI elements. Since the Activity is still visible while running onPause() the user will see the actual UI elements becoming destroyed. This is ugly and not what I want.
So my question:
Is it safe to release memory (destroy UI) in onStop() (according to documentation the Activity is not visible when onStop() is called)?
Is onStop() reliable?
Is onStop() guaranteed to be called every time when onPause() is called?
Edit:
I feel I must explain a bit more clearly what confuses me. According to developer.android.com:
...for those methods that are marked as being killable, after that
method returns the process hosting the activity may [be] killed by the
system at any time without another line of its code being executed...
The onStop() method is marked as "killable".
Does the above mean (especially the "after that method returns" part) that the entire scope of onStop() is guaranteed to run, but once it returns nothing else is guaranteed any runtime (e.g. a spawned thread started in onStop())?
Or does it mean that onStop() might get interrupted even before it reaches the end of its scope (as of the killed at any time part)?
Or does it mean something else that I - in my divine stupidity - don't see.
The difference is that the activity sees to it that onPause should finish executing first before "destroying" the view, while onStop is a lifecycle stage that follows after the view is already in the background - meaning the activity is not visible anymore.
doing things inside onPause makes sure that the items you need to save are still intact before letting go of them - for example you need to save the text in your EditText, or the on/off position of RadioButtons, etc.
deallocation however doesn't need any of these things anymore, so it should be fine if you do it in your onStop
onStop() should be safe and reliable enogh for your purpose.
"Guaranteed" is relative in this case, given that your activity may be killed without any notification. But in that case your memory resources are released anyway.
it's as safe as anything else? Worse comes to worse your app will be killed with onDestroy. In mobile development, you basically have to assume that at any given moment your app could be killed.
It's been reliable for me in releasing media objects for a while now.
Not really guaranteed, as sometimes onDestroy is called depending on what's going on.
No, it is not safe as only onPause() is guaranted to be called. onPause() means that yor activity loses focus - perfect place to give away not necessary resources
Related
When an Activity goes in pause state, an instance of it remains in the Activity stack that is managed by operating system. And I know after a while, it destroys the instance. Now my question is whether the onDestroy() method is called when operating system destroys the Activity instance after a long while?
Like if I put a Toast inside onDestroy() method, that will be shown when the Activity instance gets destroyed by OS? (I know it will be shown by pressing back button).
The nature of this question makes it hard to test because sometimes it takes a day or more for OS in order to destroy an Activity instance in stack.
There is no guarantee that it will be called. You can see Activity#onDestroy for that.
Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.
By simply killing it could be e.g. a System.exit call or something similar where it skips the lifecycle hooks.
I always think finish() will fire onDestory() immediately.But in 4.3 it seems not the truth.
I just want to know in which condition it'll happend ?
sorry,I can't put all my code on here.
It confused me a few hours,and I can't find any useful info about it.
From the docs:
onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() and onDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage.
It doesn't matter if you used finish() or the system killed your Activity on its own. If the system "wants" to recover memory, there's no guarantee that onDestroy() or onStop() will be called.
First, this answer assumes that you are referring to Android's Activity class and its finish() method and onDestroy() lifecycle method.
Second, it depends upon your definition of "sure":
Your process could be terminated in between finish() and onDestroy(), for reasons independent of whatever is triggering the call to finish()
A device manufacturer or ROM modder could introduce some screwy change that would break the connection between finish() and onDestroy()
The battery could go dead in between finish() and onDestroy()
Etc.
No, there is no guarantee onDestroy() will be called.
The same goes for onStop()
What you want instead is onPause()
This is true for all versions of Android, going back to 1.0 to the very latest. The Activity lifecycle can be initially very confusing for beginners. But it's not the beginner's fault, it's the fault of the framework designers.
Another mistake beginners make is to assume that onResume() is about resuming the Activity, when in fact it's the UI thread that is resuming while it is in its Activity. This is another point that the documentation goes over and over again, but really, it would have been a lot simpler if the android team had called that method something less ambiguous to begin with.
according to: http://developer.android.com/reference/android/app/Activity.html
Will allways be called,
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.
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
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.
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().