I am using a WebView in my app's sole Activity. Whenever the user clicks on the BACK button, I override the onKey and process some clean up before calling finish of the activity.
I see that once in a while (maybe 1 out of 20 times), onDestroy is not called. And in this case, if I launch my app again, a blank screen comes up. The Activity's onCreate is not called, and neither is my overridden Application's onCreate.
Does anyone know why this happens, and are there any possible solutions?
Thanks,
Rajath
Based on the little less than a line of code you have provided, please do the following:
Stop overriding back key.
Do the cleanup elsewhere, e.g., in onPause().
It turns out that I was capturing uncaught exceptions using the UncaughtExceptionHandler(). So, sometimes when the app was actually crashing in onDestroy(), the subsequent session was not properly launched.
Of course, in the case where the app's onDestroy() was not called at all, the problem is still fixed when I don't use UncaughtExceptionHandler(). Not sure why though.
-Rajath
Related
The above issue arises once in two debug. And the weird thing is app doesn't crashes, it stops responding.
What does this mean? And what wrong is happening inside?
You should really read the documentation on this, it will help you out a lot.
The savedInstanceState field is set when your Activity is being re-created from a previous instance. This happens e.g. when the device changes orientation or when the user navigates away, and then navigates back to your Activity. When the field is set, this allows you to restore the state of the Activity as the user left it.
The savedInstanceState field is null when your Activity has no previous state to restore from.
When your Activity is about to be destroyed, you can add variables to the savedInstanceState by overriding onSaveInstanceState(Bundle bundle) in your Activity, and adding them to the Bundle. The next time your Activity's onCreate(Bundle savedInstanceState) will be called, the fields you set in the onSaveInstanceState() will be available to you in the Bundle.
Finally, the "application not responsive' dialog is shown when you do too much work on your application's main (UI) Thread. However as pelotasplus mentioned this may also occur when you connect the debugger. If this dialog is shown when you have the debugger attached I wouldn't worry about it. However, if this dialog is shown during normal use of your app, this indicates you perform too much processing on the main Thread and you should move the heavy lifting to background threads, e.g. by using Loader, AsyncTask, IntentService, Thread or any of the other options available for this.
There are two things here, first of all
saveInstanceState = null
you see in your debugger is nothing unusual. Sometimes it's null, sometimes it's not. This is how Android framework works ;-)
For more information about that go read official docs about Activity lifecycle: https://developer.android.com/training/basics/activity-lifecycle/recreating.html#RestoreState
Second thing is that ANR (application not responding) window which happens a lot when debugging your apps. Just press WAIT and you are good to go.
I have an activty and when it loads the first time it does some stuff OnCreate that i also needed to run when OnResume, the problem is that the first time it comes into the activity it goes through both OnCreate and OnResume, if I navigate to another activity and then use the back arrow to go back to the activity it only triggers OnResume, which is fine except when it goes through it when the activity is being ran for the first time, its causing it to call the same thing twice. How can I avoid the activity not calling OnResume() the first time if at all possible?
How can I avoid the activity not calling OnResume() the first time if at all possible?
It is not possible. It is specifically designed this way, so that you don't do things twice.
when it loads the first time it does some stuff OnCreate that i also needed to run when OnResume
Move all of that "stuff" into onResume(). That way, the work is done regardless of whether the activity is first coming onto the screen or is returning to the screen.
You may wish to spend some time reviewing the activity lifecycle.
That is how android activity lifecycle works.
One way to avoid this issue is, simply move logic to onResume()
This is due to the nature of the Android activity lifecycle. Please read Pausing and Resuming an Activity for more information.
Cheers!
If you still wanna try other solution to not run the code that you wrote in onResume for the first time when onCreate called. You can add the boolean value assign it true value in onCreate and in onResume check if it is true then skip the code else run the code that you wrote on the onRusume.
I've got an app that is complete, apart from the lifecycle that, guiltily, I left as last.
Things seem to work good in all cases, but one:
When I pause the app by pressing the power button, it correctly pauses and restarts when resuming.
When I rotate the screen it correctly resizes.
When I pause AND THEN rotate the screen, its behaviour is different and the app resets.
Now, obviously it's a problem of my internal code, but to help me in the debugging, I would like to understand what's the difference between the three lifecycles. Or better, if the THIRD example is some how different from the first two.
With debugging I saw that all of three do this (I resemble by mind, I hope to be right):
onSaveInstanceState()
onPause()
onStop()
onStart()
onResume()
Is it right? Or do I miss some lifecycle steps in the third example, above?
Thank you.
Please specify what you mean by the app resets.
When you press the power button, most likely your app stops. That's why you see onStart() being called after stopping (not: pausing) your app.
Given that, is it really the case that the third scenario you describe is a combination of the first two? In other words, how do you pause your app in the third scenario?
Update Regarding your comment: There is a difference between your Activity being stopped and your Activity being destroyed.
Rotation is a configuration change. In this scenario, your Activity is going to be destroyed and re-created. You can handle this case separately if you must (it depends) through the onRetainNonConfigurationInstance() callback and the getLastNonConfigurationInstance() method. Android will call onPause(), onStop(), onRetainNonConfigurationInstance() and onDestroy() in this order, and then continue with onCreate() etc and it will not handle any events in the meantime so that they won't get lost.
Most likely, some of your code is located in the wrong callback, such that in the third scenario, something does not get initialized/attached/... This is really hard to tell without the code and the exception (if it is an exception).
I suggest you proceed as follows.
Complete your understanding of the lifecycle and be precise (creation, start, restart, resume, pause, stop, destroy)
Complete your code to override the other lifecycle callbacks as well with log messages (don't forget to call the super class' callback) and analyze pause, stop, rotation and combinations
Identify the point of the crash
Analyze the life cycle of the objects involvedd in the crash in conjunction with the Activity lifecycle
Or you can post some code and the exception here, of course.
Update 2 I have made a test on an AVD. I have observed the following:
When the AVD is in landscape orientation, and I press the power button, my app receives a configuration change to portrait orientation (presumably because the portrait-orientation-only lock screen takes over). Pressing power again and unlocking the AVD, the app receives a configuration change again back to landscape orientation.
While not solving your issue, it goes to show that code must be carefully placed in the respective callbacks, because in the case above, while being re-created, the Activity will still not be shown.
Drop me a comment if you update your question.
Hi you can check the documentation regarding Managing the Activity life cycles in android .
When orientation changes Activity is re-created.
Add android:configChanges="keyboardHidden|orientation" to your activity in the manifest.
My app is retaining all of the variable values when it closes and this is effecting how it runs when reopened. Is there any way to reset them all upon app close? or is there a way to clean the app from memory when it is closed so to speak? For the moment I have just been setting all of the important variables "=0" in the last few lines of execution but I know there must be a correct way to doing this.
EDIT:
OK I thought that it would just be easier to reply here instead of individually to everyone.
The app is indeed staying alive in the background, I checked with advanced task killer. How would I get the ap to "Die" by presing the back button? I think this would be the easiest solution given how the app works:
open app > press start button > press stop button > results screen > press back button to exit.
so basically each time the app runs should be an independant execution.
Override the onPause, onResume, and onDestroy methods. onPause should save anything upon pausing, onResume should reload these values when it is resumed, and onDestroy will be called when your app closes. You can clean up stuff in onDestroy. See this link.
You app is probably not closing but remaining in background. Check advanced task manager and see if the app is running or not.
You need to familiarize yourself with the Activity Lifecycle.
You could leverage onResume() to reset your variables; also note onDestory() and onPause().
UPDATE:
Killing the application in its entirety each time the app moves to the background is an anti-pattern. You should really look at your application and follow the aforementioned activity lifecycle pattern and take the needed steps to insure your variables exist as you desire based on state.
I like what #Alex and #Jack said. To add to that, also consider that you can call finish() in your Activity if you want to force it to close up and return to the last Activity. Going along with this, also consider the use of setResult(int) (JavaDoc Here)
You can also set a flag on the Intent when you call the Activity you are questioning about. A flag like FLAG_ACTIVITY_NO_HISTORY could be helpful:
If set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished. This may also be set with the noHistory attribute.
List of Intent Flags
Uninitialized variables are bad. Don't do it. ALWAYS manually reset variables before using them for the first time.
the onResume() method will let you reset the variables when the program resumes, but will also do it when you return to the activity unless you add the logic that says you are coming from in the app, not the home page. Maybe onRestart() is what you really need? I'm not positive, but it's possible with onResume.
When I run my app on the debugger, I get the main thread and 3 binder threads.
On a button click I call Activity.finish(), which looks like it ends the activity as the UI closes and goes back to the home screen.
However, in the debugger, it still shows the main thread and 3 binder threads as "(running)".
I am baffled to why this is happening. Even more so, it is causing my app to call Activity.onResume() when I run it again after exiting the app.
I currently override these methods in the Activity, but I call the appropriate super functions in each one:
onDestroy()
onPause()
onResume()
onSaveInstanceState()
Any help or advice regarding this is much appreciated!
You don't control when your app leaves main memory, the OS does. Look closely at Activity.finish...
Call this when your activity is done
and should be closed. The
ActivityResult is propagated back to
whoever launched you via
onActivityResult().
Note that is says nothing about memory. As to calling Activity.onResume, that's exactly what you would expect for the lifecycle; remeber that onResume is not just called after a resume but even when the app is first launched after onCreate.
While not exactly what you asked I suggest you read this article about exit buttons which goes on to say something very important
[Activity.finish] is exactly equivalent to hitting the back button.