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.
Related
I understand the basic Lifecycle of Activity/Fragment but sometimes, when user puts the app in background state for long time I'm not sure what's going to happen when he opens it again. Recently I've encountered a bug: User gets nullpointer exception by calling method of a view saved in class variable (textView = findViewById(...)), inside fragment's OnResume method. The variable is set in OnViewCreated(). Is that possible that over long period of time fragment might lose it's fields due to lack of memory? When onResume() will be called and when onCreate()?
If the app is in background for a long time its process will be killed by OS, or if the device is running low memory. To test how your app works under these conditions use flag "Do not keep activities" in Developer options on your device. In the described case onCreate will be called when Activity will come to the foreground.
If the process is not yet killed then onResume will be triggered. Normal variables persist, but the problem is that you can never be sure when you're calling onResume and when you're calling onCreate (since you have no control over when Android just goes and tosses stuff on the stack out the window... anything not currently being used is eligible for destruction).
So my solution is to add a null check with if condition: if the variable is null then initialize and perform actions, if not then just preform actions.
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
I have an Activity that should only get created once. That is, onCreate can only be called once. If it's called again, I want the Activity to do nothing.
Is it advisable to do the following?
protected void onCreate(Bundle savedInstanceState) {
this.setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
if(onCreateWasCalledAlreadyBoolean) {
setResult(RESULT_OK);
finish();
return;
}
//Do other stuff here
}
I assume you understand how the activity life cycle works. I mean, you are not trying to avoid something that does not apply here (thinking that onCreate may be called multiple times whenever it just onRestarts etc.).
Technically, it's perfectly fine.
However, you should be worrying more about why you need to call your activity ("A") again if it shouldn't be created at all, if that's what you're thinking.
If you've caught yourself checking if your activity A was already "called" (?), this could mean the previous activity ("B") has a mistake in the logic flow of the app, and that B instead should be checking if it must in fact start that activity A. I mean, if you need to decide if you must call an activity, check before starting it.
I don't think that's applicable if you're restarting the activity (e.g.: go Home, then navigate back), but then again you should be restarting it from where you left (B for what I can tell). You won't be navigating back to A. And you didn't give much detail, so I'd guess this is some kind of splash screen, like evilmage93 said.
If that's indeed some kind of splash screen, I would advise to show it whenever the user navigates back all the way to remove your app from the task stack (contrary to his advice). In other words, whenever the user restarts the app from its "front door".
Although that's ultimately a design decision, I prefer to see the splash screen whenever the app is being loaded ("entered") in the stack for the first time, and it should work fine if you (obviously) finish A before calling B (the splash screen is supposed to finish itself when done, even in its first run). It's a matter of consistency: the same app should behave the same way whenever the user performs the same task (start app from its "front door").
Still, I answered your question covering some general aspects because you asked in such way.
// edited:
Finally, by looking at that onCreateWasCalledAlreadyBoolean I'm afraid you may be trying to reinvent part of the activity life cycle mechanism. In this case, don't: proceed with your regular activity logic because the user expects that behavior. Generally I wouldn't advise people to break the normal loading of an activity just because it was killed and restarted by the system.
I don't see why not. Wouldn't it be simpler to not restart the activity at all though?
What are you worried about NOT being okay? Performance..Uncaught exceptions..Code clarity?
I have finished the Layout exercise and wondering why they include the call to populateFields() in both onCreate and onResume.
According to Activity Lifecycle "onResume" will always be performed before the Activity is shown so why not just there?
I have real production code that populates fields and is only called in onResume and it works just fine.
I thought one reason would be that maybe onResume is called after the activity is shown, but a bit of googling digs this (mostly unrelated) thread:
http://groups.google.com/group/android-developers/browse_thread/thread/ddea4830bedf8c6c?pli=1
Quote: onResume() is thus the last thing that happens before the UI is shown
This is what Dianne Hackborn says so i guess we can trust her :)
Actually I have seen apps (in my app and also others), where fields were only populated in onCreate(), but not in onResume().
Lets call that app 'A'.
The effect was that when the user pressed the home button, went to a different app, and then returned to 'A', the screen stayed black, as 'A' was still in memory and thus the system did not bother to call onCreate(), but directly went into onResume().
So basically I'd say (and this seconds what #Torp wrote) populate the UI in onResume() and be done.
But then, this answer is slightly off-topic as it does not answer your "why" question.
You don't populate in onResume because it will be called every time the activity is shown.
You generally want to create as few objects as possible, so you create them once and for all in onCreate, and then you can always check that they are still updated in onResume.
I have read the other window leak posts and have tried what what suggested there to no avail.
I have 3 activities: A, B, and C. Activity A gathers information from the user. Activity B displays a spinning ProgressDialog while it communicates with a server on another thread. When the thread finishes, it dismisses the ProgressDialog and starts the next activity. Activity C displays the information from the server to the user. Activity B is set up so that when the user hits back from C, they fall back to A.
It is important that these tasks be in separate Activities.
As of now the app successfully does what it is supposed to in most cases, except in the following scenario: If the user changes the orientation while in activity C before returning to Activity A, the app crashes due to a window leak.
I am dismissing the ProgressDialog inthe onPause() of Activity B before istart C.
I have tried dismissing the
ProgressDialog on the main thread
using a handler as well as in the
separate thread.
When the user does not change the
orientation in C, no window leak
occurs.
Any ideas? TIA
This often happens where ProgressDialogs are used. I experimented with ProgressDialog a while back and found the thing to do was dismiss() it from onPause() and create it anew from onResume(). The background task obviously needs to survive your Activity & dialog so I used onRetainNonConfigurationInstance() to pass the task instance from the destroyed Activity to the new one.
An alternative, cheatier workaround might be to simply prevent your Activity from being destroyed and created anew merely because the screen orientation changed. Do this by adding android:configChanges="orientation" to the tag(s) in your AndroidManifest.xml.
I solved my problem by completely changing how i handled everything. I now have only two activities (A and B) and display the ProgessDialog in activity B while handling the savedInstanceState as needed in order to work around the problem.
Even though I have fixed the problem on my app, I still dont know why it was occuring before and would like to learn more about window leaks and why i was having problems. If anyone knows more about the problem i was having, please post as I'm sure there are others with the same problem.
Thanks
Not sure if this was related to your specific problem, but I had a similar issue which had to do with leaky windows for dialogs that are created in the onCreate method of an activity. So if your activity starts up showing a dialog, and you do a config change, the OS remembers which dialogs were shown, so when the activity is killed & restarted, the OS attempts to restore your old dialog while your activity tries to show the same dialog again (since it's in onCreate). I found by only showing the dialog during onCreate if it's not a config change (ie. savedInstanceState != null), the leaky window problem went away.