I’m interested in what actually happens when Android app crashes. Imagine such a situation - we have an app that doesn’t use any custom exception handlers, just stock Android behavior. Then for what ever reason the app crashes and Android tries to either recreate top most activity(if it has the valid state) or throw it away and switch to some parent activity , but where this actually happens ? Is this happens on the very same process the app was running before the crash on Android setups compleatly new process for this reason ? Thanks !
Application process will not be recreated if activity crashes.
Process can be stopped if there is something unexpected happened at application level. Its very rare.
Application process are maintain by OS. If you want to stop process on activity crash then you have to programaticall tell OS to kill underline process
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
All the processes are managed by OS. OS can terminate process(in case low memory) and save instance of process in cache. So when next time application starts it uses saved state from cache togive user seamless experience
If you see application callbacks there is no callback like Activity callback onStop or onDestroy. There is callbacks like onLowMemory, onTrimMemory and onTerminate
For more details visit https://developer.android.com/guide/components/activities/process-lifecycle
and
https://developer.android.com/reference/androidx/lifecycle/ProcessLifecycleOwner
Related
I have an app with a service (onStartCommand return START_STICKY). All works fine, the app and the service are restarted if I swipe the app away or I reboot the device. This works.
But:
The app is restarted from time to time (sometimes after minutes, sometimes after an hour). This means, the app is killed and restarted. But I don't know why.
Any hints?
Another process who kill my app?
Maybe an error in my code?
The OS?
Maybe you can give me a generally hint or a direction to search the error.
Thanks
Hans
In general, you can never make an assumption that your service will not be killed.
You just have to design the app to resume your process with the state of it being killed by OS.
OS can kill your app whenever it thinks it unnecessary to keep it in the background. Your flag START_STICKY will get your service back to background, but this flag doesn't mean it will run forever without being terminated.
So make sure to use onSaveInstanceState() to keep your important states or data, or even SharedPreferences to keep the data in local storage just in case your app doesn't save states.
This link might help you: Android - Lifecycle and saving an Instance State questions
We have one very difficult to reproduce problem with an app. The use case is as follows:
User opens app
User leaves app in background
User openes 5 to 7 more apps
System kills our app
When user tries to resume app, app crashes due to NullPointerException
I was trying to use console log with Application class method onTrimMemory() and onLowMemory() but this methods are not being called. Is there any method or callback I can be listening to know when android system will kill my app due to many more apps being opened and in that case for me to do something?
You can save whatever states you need in onSaveInstanceState() and restore them in onRestoreInstanceState(). onDestroy() is what the system will most often call to clear room while your Application is in the background, but it is not guaranteed to be called, so it is better to have already saved your states in onSaveInstanceState().
Is there any method or callback I can be listening to know when android system will kill my app due to many more apps being opened and in that case for me to do something?
Not really. Depending on circumstances, onDestroy() of running activities and services will be called.
We have one very difficult to reproduce problem with an app
That should be reproducible in a matter of seconds:
Run your app.
Switch to another app.
Kill your app's process from your IDE (e.g., "Terminate Application" toolbar button in "Android Monitor" tool window).
Try returning to your app from the overview screen (a.k.a., recent-tasks list)
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.
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 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.