I am starting up my app in the emulator and seeing a call to onDestroy() on the starting activity. Android doc seems to suggest that onDestroy() is called only when the app is stopped. Are there other circumstances when it can be called? It causes a problem for my app because I am shutting down an executor in the onDestroy() method (which was created at class loading time). The first attempt to use the executor then throws a RejectedExecutionException. I'm guessing this is because I have shut it down.
Wisdom gratefully received.
onDestroy() only gets called when your app is being shut down. Here are some things you can try:
What happens of you remove the code to shutdown the executor altogether?
What happens if you instead move the code to onStop()?
Are you sure onStop() is not being called on a previous instance of you app already running on your device. (i.e. you install the app, make changes, install it again, the first one must stop.)
Related
I'm writing a game that players take turns in. At the end of a turn, I send my data to the server and update my database to let me know that it is now the other player's turn. The problem is, what if someone were to kill the app mid-turn? I'm talking going to Task Manager and actually kill it.
I read that onDestory is not always called, so that's a no go. I was then thinking onStop, but onStop is called in other places too. So how can I be sure that the app is actually getting killed and they aren't just like putting the app in the background for example?
Edit: I should also mention this is in a Fragment that I'm checking this, but don't think that'd make a difference.
I am not sure if this will help you solve the problem completely, but if you want to use onStop() instead of onDestroy(), there is a way to distinguish between a call to onStop() because the activity is dying and a call to onStop() because it's just going to the background:
if (this.isFinishing ())
{
// activity dying
}
else
{
// activity not dying just stopping
}
However I do want to point out that although onStop() MIGHT be more reliable that onDestroy(), it's still not guaranteed to be called right away. In my experience onStop() is called eventually, but maybe some time later.
In your example, there is no method that gets called. The Linux process hosting your application is killed, interrupting the Java Virtual Machine running your application's code in the middle of whatever it was doing. The application ends without any notice or warning - even finalizers don't run, because there's not really any "cleanup" needed.. the memory is simply reclaimed by the Linux system.
What you should do is design your application architecture so that if one of the players times out (application is killed, network connection is broken, battery dies, phone gets dropped out of a car and ran over by a truck and tossed into a lake), the server is able to detect the timeout and handle the situation accordingly - most likely, end the player's turn for him and move play onward.
You can use the following method. Its called when you swipe the app from the recent list:
#Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.e("onDetachedFromWindow", "activity dying");
}
When I stop a service using the stop button under the Running Services tab, the method onDestroy() is called.
But when I force stop the application, onDestroy() is never called.
Any explainations about this?
or maybe a solution to fire onDestroy() when force-stopped?
When your force stop an app, exactly that happens - It is Force Stopped. No warning, no callbacks, just stopped. The entire process is killed, and none of the running components (Activities, Services etc) are given any warning.
There is absolutely no guarantee that onDestroy() will be called. Move any application critical code into onPause(), which is called under most circumstances.
From the documentation:
Once the activity is created, onPause() is the last method that's guaranteed to be called before the process can be killed... onStop() and onDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage.
To reiterate this point, Force Stop isn't intended to be graceful and exit the app in a caring manner. If you have critical code that must be run each time app finishes you need to run it in onPause().
When the application gets force stop, Process.killProcess() is called but not onDestroy() function. Go through this link. You will get some idea.
Android force Stop callback to application?
I am assuming you have code that you want to execute in onDestroy() referring to your line:
"or maybe a solution to fire onDestroy() when force-stopped?"
The Service method public void onTaskRemoved(Intent rootIntent) is what you are looking for, it will be called when the app is force-stopped.
I know it's an old question, but I was having the same issue and in my case I was using a binding service, so even after called stopSelf() Android does not call onDestroy() method, in order to force it I need to call unbindService() first
I have a bug I'm trying to analyze that occurs when the Activity's onDestroy() method is called after hitting the back button. I've put breakpoints in the offending code (using Eclipse). The debugger pauses the app at the breakpoint, but the Android system also takes the app off the screen and returns to the phone's homescreen. After the app is paused for about 10 seconds, the app's thread seems to get destroyed by the Android system because the debugger suddenly disconnects.
Any ideas on how to keep the Android system from doing this? I need to keep the app alive so I can step in the debugger, look at variables, etc.
Phone is running Android 2.3.5.
A workaround that I found is to put a startActivity() call into onDestroy() (before super.onDestroy()) that starts a dummy instance of the Activity, just to keep the app alive. The Android system won't garbage collect the app thread because there is still an Activity running within it (the new dummy Activity). This in turn allows you to debug things because the debugger's connection to thread won't be lost.
If the phone pops up a dialog saying the app is not responding (Force Close or Wait), don't click Wait, just leave it alone. It seemed that clicking Wait caused the app thread to be killed and a new thread was created for the dummy Activity.
You can try a breakpoint on super.onDestroy(), but I suspect you'll have the same luck. :(
Android won't let you linger in onDestroy, it will timeout, so try to accomplish your shutdown more quickly. onDestroy() is intended only for freeing resources and isn't always called before termination; data should be persisted in onPause() or onStop().
https://developer.android.com/training/basics/activity-lifecycle/stopping.html
Addendum: Other options include using a background service for some of the work or to manually handle the back button to give yourself more time, but it could negatively impact user experience.
http://www.stanford.edu/class/cs193a/03/
sent from my phone, please cut my thumbs some slack.
I want to execute some functions when the program is exited by hitting the back button.
This is now done by onDestroy() which works in every case but one. When coming back from another activity in some cases on exiting the program, onDestroy is not called.
I know that in theory onDestroy should only be called when Android closes the app due to low memory, but for me, onDestroy works always and only in a very special case it does not.
Using onPause or onStop does not work because I only want to call the function when the program is exited but not when just another activity is called.
So is the last way to catch the back-button-click and call the function there? Or is there any other solution?
Tactically, use onBackPressed().
Strategically, reconsider your architecture. A well-written activity should not care if onDestroy() is called, as it is guaranteed to NOT always be called. For example, Android can terminate your process whenever it wants (e.g., extreme low memory conditions). The fact that you need onDestroy() to work reliably suggests there are problems that should be resolved.
IIUC, there should only be one instance of a given Android service, it is a singleton.
However, my service gets instantiated multiple times, although I
do nothing for it.
When the service crashes (for example when I uninstall the app through adb), it
gets scheduled for restart ("Scheduling restart of crashed service.. "). I
understand this is an effect of the service being sticky.
After that, when my app starts, it calls startService() and bindService(), and
the service gets appropriately started and bound. But the service is then
reinstantiated and onCreate() is called repeatedly, as many times it was
scheduled for restart.
Each instance then wait for clients to bind and register, but onBind() is only
called in the "main" service instance. The additional instances wait a bit for
client to bind, and since that doesn't happen, they call stopSelf().
But stopSelf() has absolutely no effect in these "dead" instances, onDestroy()
is never called.
The "main" service instance does work as expected, and when it decides to call
stopSelf(), onDestroy() is indeed called.
Worse, all these dead instances accumulate, they never gets destroyed.
Therefore, their only possible end is a crash (which happen every time I
launch/install through adb), and thus scheduled restart.
So that in the end I get many of these dead instances, which are restarted
progressively once by minute approximately.
Does anyone know what's going on?
I got similar behavior if I use eclipse to restart an app with a remote service. According to logcat, system consider the killed service had a crash and tried to restart the service. At the same time, the service has been restarted with the restarted app. For some unknown reason, Android system does not realize there is already a running service, and tries to start a new one.
It happens several times on Optimus one, Galaxy tab, and EVO 3D. It is fine with Nexus one.
Because I haven't seen your code, this is just a guess: Maybe you have a memory leak that prevents the service from destroying properly. That's the only reason I could think of to get multiple instances of service. For example, if you service is holding on to some object that also have a reference to your service. It happens a lot with inner classes.
Check out this video from Google I/O to see if this problem applies to your services and how to find it: http://www.youtube.com/watch?v=_CruQY55HOk&feature=player_embedded
if you use the section to be excecuted in onstart() . if ur starting the service by onclick button or like clicking on icon multiple time means ,what it will do is if service is already running means ,it will go to onstart(),so the method is excecuting again and again its not that service is starting multiple times .... ur method is running for multiple time ,This i told accornding to my guess may be exact code will be Explaind properlly
if your app exit on crash or kill the process it belongs to like System.exit(), it will start after your app exit or start if your service is running in the same process with Application.
Because you kill the process, and Android detect your service should not stop, so Android restart it for you after your app exit. And why service start again after app restart, I think it is Android's bug, it reallocate a new process to your app instead of using the process allocate to your service.
So, how to solve this problem?
just set the attribute android:process=":background"(whatever you want here, starts with :) to your service node in AndroidManifest.xml. hope it helps you.