If Java provides Garbage Collection, then what is the need of onDestroy() in Activity Lifecycle?
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.
Here is an example......
public void onDestroy() {
super.onDestroy();
}
OS decides when things "go away." The onDestroy is there to let your app have a final chance to clean things up before the activity does get destroyed but it does not mean that the activity will, in fact, be GCed. Here is a good article that I recommend people to read that relates to creating an exit button. While it's not exactly what you asked about, the concepts will help you understand what's going on.
You can use onDestroy() to finalise the program. I have used it in the code bellow to tell the server that the client is closing its socket to the server so I can notify the user on the server end that the client has disconnected.
client:
...
protected void onDestroy(){
super.onDestroy();
if(connected) {
clientMessage.println("exit");
clientMessage.close();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
finish();
}
...
server:
...
while (connected) {
input = clientMessage.readLine();
if ("exit".equals(input)){
break;
}
...
}
...
onDestroy() is a method called by the framework when your activity is closing down. It is called to allow your activity to do any shut-down operations it may wish to do. The method doesn't really have anything to do with garbage collection (although your shut-down operations—if any—might involve releasing additional resources that can be gc'ed). In particular, it has nothing to do with C++ destuctors (despite its name).
If you have no shut-down operations to do, you don't need to override it. The base class does essentially nothing.
onDestroy may be called when an activity is destroyed, but you can not count on it. 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.
See: http://developer.android.com/reference/android/app/Activity.html#onDestroy()
In the Android Activity Lifecycle's onDestroy docs:
onDestroy() is called before the activity is destroyed. The system
invokes this callback either because:
the activity is finishing (due to the user completely dismissing the activity or due to finish() being called on the activity), or the
system is temporarily destroying the activity due to a configuration change (such as device rotation or multi-window mode)
The Activity#onDestroy() API docs also answers it quite well:
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. source
As the quote from the docs say, its for preventing a destroyed activity leaving things around (e.g. memory leaks through referencing, threads), but only when the rest of the app still runs. If the application process ends, it doesn't matter if you forget to clean up threads or other resources since the OS will do it for you. You don't need to override onDestroy.
There is no need to do what sam786 is doing (overriding and just calling the super method) as that is absolutely useless. All other answers seem to go along the lines of "clean up", but don't explain what kind of clean-up or when. You should not be saving any data in onDestroy(), as you can't guarantee it will be called, so you will lose data sometimes. It won't be called when you press the home button, for example (the case where you want data to be saved).
The onDestroy is there to let your app have a final chance to clean things up before the activity does get destroyed
Article Exit Button in Android
It gives your program a chance to do things like cleanup resources (say threads) so that they don't pollute the associated application. If you don't have any use for it, then don't override it.
See:onDestroy()-Android Reference
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 am making an Activity that logs a message when the activity is destroyed due to orientation change.
What I want to do is to call that Log.d() UPON the moment the activity is destroyed.
In other words, I don't want to call it by checking savedInstanceState==null after the activity is recreated.
Is there a way to know why the activity is destroyed before I reach onDestroy()? Thanks
You can use isChangingConfigurations() from the docs:
Check to see whether this activity is in the process of being destroyed in order to be recreated with a new configuration.
Docs available here
If I understood correctly you want to log something before destroying activity.
According to the lyfecyle activity diagram you should do that at this point.
In your activity maybe you have to overwrite onDestroy method and call log before the super call.
#Override
public void onDestroy() {
//log
Log.d()
super.onDestroy();
}
EDIT:
Juan is right, as the docs mentions:
"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."
https://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29
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 have a method like this in my class which extends Activity
#Override
public void onDestroy() {
Log.i("onDestory: ", "Inside OnDestory!");
bluetoothCommunicator.destroyedApp();
super.onDestroy();
}
The method destroyedApp() look like this:
public void destroyedApp() {
if(server != null)
server.destroy();
}
Where server is an Instance of a class which extends Thread
Here is the scenario:
I'm opening the application for the first time, inside my onCreate method, I create a new instance of the bluetooth class which sets up the BluetoothServerSocket, this works fine and I'm able to transfer files to my phone.
This also works when I have my application in the background, because the thread is still alive.
But
When I'm killing the application, according to the Activity Life Cycle
The onDestroy() method should be called by the Android Framework. And when I'm launching the application once more, the onCreate method should be called, but it doesnt seems that an instance of the BluetoothServerSocket is being created. I have no LogCat info, because the device which sends the bluetooth file, only says:
Error Log:
Write Error:
Transport endpoint is not connected
__obex_connect:
error=-2
Unable to connect to the server
Error
Which tells me that the BluetoothServerSocket is not "alive"
Any suggestion on how I can accomplish this?
There is generally no guarantee that the onDestroy() method will be called at all. According to the docs:
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.
Derived classes must call through to the super class's implementation of this method. If they do not, an exception will be thrown.
So I would first test if it is being called reliably.
Also, you are callling super.onStop() in your onDestroy(). It should be super.onDestroy()
Since I cannot comment, I am posting here.
As, commented by Egor I dont think you can call onStop() from within onDestroy(), Android will itself call onStop() following onPause() depending on the memory.
Now, note that stop(), suspend() and destroy() methods of thread are deprecated, the only safe way of terminating a thread is to have thread exit its run().
Now, when you are calling server.destroy(), there is a possibility that it still holds some link in the memory and therefore Garbage collector will not be able to garbage collect your activity. Hence, I believe this could be the possible reason why your onDestroy is not called.
Point me if I am worng.
How are you killing your application? I was looking for a solution for your problem in the Application class and I came across this information about the onTerminate() method:
This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.
I remember I had a similar problem in one of my apps, where some components' onDestroy() method was not called because I used the "Clear memory" button in the Task Manager (Samsung Galaxy 2)
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