I have an activity with in which there is a async task that will do some download stuff. AT the time of downlaoding it will show a loading dialog.
My problem is, it worked fine for me when me doing it in only one orentiaon. But when i rotate at the time of download, it shows window leaked and will crash at the
dialog.cancel in my post excute.
From my study on it more i understood it due the change in the context when device is rotated.
That is when a device is rotated the activity will be recreated so the context will be changed.
But i have created the dialog with old one and that wasn't the current context. So when i cancel it it shows error
What is the solution for this, any idea frnds.
Me using honeycomb, me tried but with fragment but didnt get a good sample for that. Me now mainly trying that,
if anyone can give me some links for that it will be
great
First of all: open your dialog using the showDialog method (there are a lot of examples in the official documentation). If you do so, the activity will take care of dismissing the dialog on destroy, and re-showing it after the activity has been recreated.
Also... if the dialog shows a progress bar (not a wheel), you will want to update the progress of the dialog after orientation changes. In order to do so, I recommend to use the onRetainNonConfigurationInstance to return the current state of the dialog and/or the activity itself. Then, you can use getLastNonConfigurationInstance to recover that state. Google about those two methods if you want to see examples.
Another thing to keep in mind: if you are updating the state of the dialog an/or any other UI element from the AsyncTask, you must be aware that after the activity is recreated, the AsyncTask may be pointing to the wrong UI references. In order to handle this, you can create a proxy class (Proxy design pattern) to detach the AsyncTask progress notifications from the current UI elements.
Related
Everywhere I can read: Use FragmentDialog everywhere because it can be independent on Activity lifecylce. But, generally, dialogs very often should be displayed asynchronically. However, it is discouraged to commit to FragmentManager from asynchrounous callback. How to deal with it?
Use DialogFragment by all means because as you mentioned it helps in keeping your activity loosely coupled with the dialogue. Yeah there are cases where you might need to show the dialogue asynchronously. In such case, what you need to do is wrap your dialogue invocation code with method calls on the host component which tells you whether it is safe to show the dialogue at this instance or not.
If you are calling show within an activity, wrap the call to show with -
if(!isDestroyed() && !isFinishing())
and If you are calling show within a fragment , wrap the call to show with -
if (isResumed() && !isRemoving())
This more or less would solve the issue of landing in an inconsistent UI state
I need to show a yes/no dialog in AsyncTask.onPostExecute() but I keep getting
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
when the screen is rotated just before the dialog is shown. I had a similar problem showing dialogs in the onActivityResult but have since moved the dialogs to the
onPostResume() as suggested by other posts but I am unable to solve this one.
Is it possible to show a yes/no dialog in the onpostexecute() without causing exception and without using "commitAllowingStateLoss"?
Your help is much appreciated.
I think you should maintain state of your activity in which you are calling the dialog, because every time when activities orientation changes onCreate() function calls and if you are initiating any AsyncTask in it, then it will execute it again. May be that's why you are facing the problem. Just maintain its state and then check it, hope it will help you.
Just add this code in your manifest file for that activity. Just type landscape or portrait according to your need.
android:screenOrientation="portrait/landscape"
Thank you.
I've got the following problem. In my app I'm loading data in an AsyncTask. The problem is, when the user now clicks on the icon to open the Navigation Drawer and opens up another fragment the app crashes. When the AsyncTask is finished the app doesn't crash. The problem that is encountering is, that when I switch the fragment (The fragments are always the same, just with another content dependent on the NavigationDrawer Item click) the app crashes.
I guess the problem is, that the async task isn't finished, I'm calling the same fragment again want to display different data.
So what would be my approach to handle this? Use for every different view a different fragment? I thought using the same fragment every time is much easier, since it's just displaying different data but the structure, layout etc. is all the same. Just the data that it gets is different.
I also thought about somehow "blocking" the user from doing any other actions while the asynctask but still show him that the app is processing. But that would be not the definition of an AsyncTask.
How would you approach it? Use different fragments for every different display? Or how? Block somehow? If a user clicks on an item of the navigation drawer the asynctask needs to stop all its actions (if some are done) and then restart doing all the actions. Is there a way to do it?
Please note that the fragment where the async is executed and the activity where the fragments are called are in two different files
You can either block the screen with a loading screen (not that good UX wise...) or you could cancel the asynctask when you change the fragment, in the destroy or detach method.
You didnt show the errors, but I would guess that the app crashes because you are trying to acess something in the asynctask onPostExecute method and it is no longer available...
I guess that it crashes because your AsyncTask is sending data to a class instance that doens't exist.You should change the Class that receives callbacks from asynctask. Anyway i can't give you a better answer till i will see your real code of AsyncTask ( at least onPostExecute() and onProgressUpdate())
use intent service to do that ask task means call ask task in a intent service that one is capable to handle background task without hang UI
Here's the scenario:
Account login page
Clicking on "Sign-in" triggers a login AsyncTask
To block the UI during network access, a ProgressDialog pops up
Upon returning, the ProgressDialog is dismissed and the user forwarded on
This flow works very well.
Here's the problem:
The user may rotate the screen while the AsyncTask is logging him/her in
Presently, the ProgressDialog is referenced by a class field, and dismissed using that pointer and call to .dismiss().
If the screen is rotated, though, everything crashes.
Probably because the Activity is re-created? My suspicion is that the closure around that field reference points to an object that is unreachable. What's your take?
How can I solve it reliably and elegantly? Just add if (... != null) checks?
More generally, I must confess I don't understand the "best practice" to apply in cases like this:
Activity A triggers an AsyncTask
The user navigates away from Activity A (back button? rotate screen? onClick that starts an Intent?)
The AsyncTask returns when Activity A is not the topmost one anymore yet its onPostExecute() has a UI effect , note: the original delegate observer is not available anymore.
Confused * (note: I am a beginner, so a thorough explanation would help me a lot)
Yes on changing the orientation, the activity is destroyed then recreated it again.
When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted. Instead, the activity remains running and its onConfigurationChanged() method is called.
Add this line android:configChanges="orientation|keyboardHidden" to your manifest file
<activity
android:name=""
android:label=""
android:configChanges="orientation|keyboardHidden" />
I recommend looking at Handling Runtime Changes. For a detailed explanation of the details of the methods available to you.
android:configChanges="orientation..." tells android your application will take care of resizing the current view hierarchy. As such, when you specify that in your manifest, your activity will not be destroyed and recreated, instead the system will just call your activity's `onConfigurationChanged()` method. As it so happens, most of the stock widgets will resize themselves when their container changes, so if you are using basic layouts, this usually "just works" by redrawing the view hierarchy in the new format. For custom widgets, this trick may not work.
The approved method is to save some configuration instance information when you are being destroyed in the onSaveInstanceState() method, and then recreate your state in onCreate()
In your case, the dialog is dismissed when then screen changes orientation, so you can either leave it that way, or reopen it in your onCreate().
I've got an app that uses ListActivity to give users a list of actions. When they click one I use an Intent to launch a separate activity.
My problem is that the actions that the app performs take about 20 seconds to finish, and since I don't want the user to receive that nasty ANR dialog, I tried to use AsyncTask to present them with a loading screen in the mean time. I tried using setContentView(R.layout.loading); on onPreExecute(), but it throws a NullPointerException which as far as I have figured out is due to the fact that loading.xml is not "a ListView whose ID is android.R.id.list".
So what can I do now? How can I show that loading screen? Is there a way around this pretty annoying situation? Any help would be greatly appreciated. Thanks!
I am not sure exactly what your use case is; you have a list of items that are populated immediately, and upon selecting one an action is taken? The action that is taken is to launch another Activity which performs background processing?
Or does it take that long to populate the list of actions?
If the former, you can use an AsyncTask for the long-running activity instead of an Intent to launch another Activity: in the callback you get for the click on the item in question, you would create the AsyncTask, and in doInBackground you would perform the long-running activity, with onPostExecute refreshing or manipulating your list as necessary.
Another thing to consider is using a dialog box to show a loading screen, if the loading is required to happen before you launch a new Activity.
If you can further describe your use case, I can help you more.
It's not the loading screen you need to have on the AsyncTask, it's that 20-second Activity initialization. I would look for a way to do all the setup in a background thread in a Service while the user is free to merrily bop around in other Activities. I'd try hard to find a way not to just stall the user for 20 seconds. Maybe take them to the target Activity and show them data cached from their last visit until the new set is ready.
Fire up and display your loading dialogs in your onCreate() of the Activity being called, then call Dialog.dismiss() in your AsyncTask's onPostExecute().