How to debug onDestroy(), Android system kills app while paused in debugger - android

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.

Related

How to tell if Android app has been terminated

When debugging an app in Android Studio, if I have an onDestroy method in the main activity and then hit the Back button, onDestroy will get called. However, Android Studio's still shows debugging. What isn't clear is whether this is only showing a debug connection between Android Studio and the device. If I go to App > Settings and force the app to close, the debugging session is terminated. This makes it seem like my app was still running in spite of onDestroy being called. But I have read elsewhere that Android will keep an app in memory for performance reasons. If the user wants to restart the app right away and the app hasn't been garbage collected, apparently it is more efficient to just restart the app that was previously destroyed.
But this raises the question as to whether you can really tell if your app has really been terminated when you press the Back button on the main activity. If onDestroy is called, does this really mean it has been terminated? I understand that you could hold a reference to some object in your code that doesn't get released but onDestroy can still get called but the app remains unterminated due to the referenced object that prevents it from being garbage collected.
Even if you write a bare bones app that does nothing but show a blank activity and hit the Back button, the heap still shows references. So I'm at a loss as to how you can tell with certainty that your app has been terminated.
This makes it seem like my app was still running in spite of onDestroy being called.
The sooner you stop thinking in terms of "app", the more success you will have as an Android developer.
In this case, you seem to be conflating "app" with "process". Your process will continue running for some time, even when you have no UI in the foreground.
But this raises the question as to whether you can really tell if your app has really been terminated when you press the Back button on the main activity.
An "app" is not terminated. A process is terminated. Your process will not be terminated immediately when the user leaves your UI by any means (BACK, HOME, whatever).
If onDestroy is called, does this really mean it has been terminated?
It means that whatever component onDestroy() was called on was destroyed, such as an Activity or Service.
So I'm at a loss as to how you can tell with certainty that your app has been terminated.
Android does not inform you when your process will be terminated, as there are many possible reasons for the process being terminated, including the user telling Android to get rid of your process.

prevent multiple instances of android app from opening

I've done a fair bit of searching for my issue, but can't find any solutions to my exact problem.
I have an app that has 3 activities in succession. The main activity (on launch), the second activity (where most of the meat and guts live), and then a final activity that is more or less a summary page of what happens in the 2nd activity.
I run into this issue semi-sporadically where if I keep the 2nd activity running in the background (turn the screen of my phone off, or just hit home) and then hit the launcher icon to go back to the app, it creates a new instance instead of returning to my 2nd activity that is running in the background. I can't find any rhyme or reason as to why it happens sometimes and not others (usually it doesn't). Most of the time it takes me right back to my 2nd activity and all is good in the world, but on occasion, it fires up another instance.
Is there anyway to check if an instance is running and ALWAYS return to that instance if there is?
When you hit Home or the screen turns off, the app automatically goes through the onStop() phase. Depending upon the available memory, the app might become a candidate to be killed by the Android OS. There really is no way to prevent the OS from killing an app that is no longer in the foreground - this is an Android OS design. This should most likely not happen if you do not have a lot of applications open.
If the first instance of the app is still around and you launch the app, it will automatically retrieve this instance. Android is designed to never create a second instance of the same app while the first one is still running. Hence there is no way to check is an instance is running. You could use logging inside onDestroy() to see when the app terminates. But again, Android does not always call onDestroy() and might just simply terminate the app.

When does the Debugger get disconnected?

I just want to ask, when does the debugger get disconnected?
I am debugging my app on the device and when I go to the background and wait some time (around 2 to 5 minutes), my app is being disconnected and I want to handle this case because it makes my app crash when I go back to the app.
Thanks!
Hi guys I know its a little late but for everyone else searching here what you have to do:
Go on your device -> settings -> developer options -> select debug app -> turn on 'Wait for debugger'
Now on Android Studio run the app in debug mode, close it and wait for the process to close (causing it to detach from the debugger) and reopen it from the recent drawer. You will get a waiting for debugger message on the device.
Go on Android Studio and press the attach debugger to process button , select the process and done :D
The same thing happened to me. In my case, the debugger was getting disconnected every time the system destroyed the app after being stopped for a while (i.e. in the background). This happens when the system needs more memory/resources for the foreground app or when your app has been stopped for too long, cf. http://developer.android.com/training/basics/activity-lifecycle/recreating.html.
The best way I have found to debug this is to add Log.d() logging (http://developer.android.com/reference/android/util/Log.html#d(java.lang.String, java.lang.String). After I started logging all lifecycle events, I found that in my case the following was happening:
I switch to a different foreground app, causing my app to go in the background in a stopped state
onPause()
onStop()
debugger disconnects (typically after a few minutes, sooner if using a memory intensive foreground app). Note that onDestroy() doesn't get called here but activity does get destroyed.
I re-launch my app, debugger is no longer attached
onCreate() - system tries to re-create activity using savedInstanceState
onStart()
onResume()
Because the system was the one that destroyed the activity, when it re-creates the activity it tries to restore the state of all Views. If you need to save additional information, be sure to override the onSaveInstanceState() method which gets called before the activity is destroyed, and then recover the saved information by accessing the savedInstanceState Bundle in the Activity's onCreate() method.
Hope that helps.

restarting an app picks up where I closed it - not from the very beginning

I thought when I exit the app on the device and it is not visible anymore in the taskmanager the app would restart from the very beginning when I start it again.
But for some reason my app keeps some variables from the previous run and does not really restart correctly.
This happens only if restarted on the device itself. Restarting with Eclipse starts the app correctly from the very start initializing all variables.
Why is this? Is my assumption wrong that when exiting the app all classes and variables will be destroyed?
Many thanks
Well, it's more complicated than just that.
First of all, you will not see the normal Android application lifecycle when you're running it in the debugger. Killing and restarting the app will indeed start you from the beginning. The normal Android app lifecycle is not very intuitive to developers, though. Normally, if a user 'backs' out of an app to the Android home-screen, one would expect your app to be killed once there are no Activities alive. This is not the case. The Android OS will keep your application alive in memory until memory pressure causes it to release the app. This is done because if the user 'opens' the application again, it will start up much, much faster. I'll point out that your Application's onDestroy() method will actually never be killed, because that surprises some developers too.
If, however, you still have Activities alive, but they are in the background, and the Android needs memory, it will kill your activities, but will call onSaveInstanceState before doing so. This will give your Activity an opportunity to save its state in a Bundle, and in fact, most of this will be done for you by the default implementation. At this point, if all of your Activities are killed, your application will be killed, but the Android will still hold onto the saved state and from the user's point of view, the application is still alive (it will still show up in the list of active applications). When the user returns to the application, the Android will re-construct the top-most Activity (onCreate will be called, but with the Bundle that contains the contents that were saved with onSaveInstanceState) and display it to the user. As the user pops Activities off the stack again, the ones below will be re-constructed, etc, etc.

Simulating activity death in Android

We know that when the system runs out of resources, an activity in background serializes its state and gets killed by the OS. When we resume it, the OS recovers the activity state by savedInstanceState passed to onCreate method. Considering we are responsible for handling what is going to be serialized/recovered, I'd like to have my activity killed in order to test the code I created for recovering. How can I achieve that? Forcing the application to be killed through the applications menu doesn't help.
Rotate your device (or emulator). Android saves, destroys, and re-creates the activity in the new orientation.
Download a task manager that kills the process in a less destructive way than "Force stop" in "Manage applications" settings. Example: GO task manager.
The task manager will kill the app (and the debug) but somehow not the activity stack (don't know why).
When you'll relaunch the app again, onCreate will be invoked with the last saved bundle/state.
The disadvantage of this solution, compared to Darrell's, is that you cannot debug it.
The advantage of this solution, compared to Darrell's, is that it is more close to real life scenario.
You can kill it from Eclipse also.
Go to the Android view. YOu should see the list of processes in the Devices tab.
Click on your process and then click the little "STOP" button.
Instant death!
FYI you can also attach the debugger this way by clicking on the little green bug

Categories

Resources