Proper way of dismissing DialogFragment while application is in background
-
27-10-2019 - |
سؤال
I started using DialogFragment, because they are working nicely through orientation changes, and stuff. But there is nasty problem I encountered.
I have AsyncTask
that shows progress DialogFragment and dismisses it onPostExecute
. Everything works fine, except when onPostExecute
happens while application is in background (after pressing Home button, for example). Then I got this error on DialogFragment dismissing - "Can not perform this action after onSaveInstanceState
". Doh. Regular dialogs works just fine. But not FragmentDialog.
So I wonder, what is the proper way of dismissing DialogFragment while application is in background? I haven't really worked with Fragments a lot, so I think that I'm just missing something.
المحلول
DialogFragment
has a method called dismissAllowingStateLoss()
نصائح أخرى
This is what I did (df == dialogFragment)
:
Make sure that you call the dialog this way:
df.show(getFragmentManager(), "DialogFragment_FLAG");
When you want to dismis the dialog make this check:
if (df.isResumed()){
df.dismiss();
}
return;
Make sure that you have the following in the onResume() method of your fragment (not df)
@Override
public void onResume(){
Fragment f = getFragmentManager().findFragmentByTag("DialogFragment_FLAG");
if (f != null) {
DialogFragment df = (DialogFragment) f;
df.dismiss();
}
super.onResume();
}
This way, the dialog will be dismissed if it's visible.. if not visible the dialog is going to be dismisded next the fragment becomes visible (onResume)...
This is what I had to do to achieve what you want:
I have a Fragment activity on which i was showing a dialog fragment named fragment_RedemptionPayment
which is globally declared at the top. The following code dismisses the DialogFragment
if it was showing before the activity goes in background and comes back in foreground.
@Override
public void onResume() {
super.onResume();
if(fragment_RedemptionPayment.isVisible()){
fragment_RedemptionPayment.dismiss();
}
}
A solution that might work is setting Fragment.setRetainInstance(true)
in your dialogfragment, but that's not the prettiest of fixes.
Sometimes I have noticed that I have to queue up my dialog actions to let the framework restore the state first. If you can get hold of the current Looper (Activity.getMainLooper())
and wrap that in a Handler you could try passing your dismissal to the back of the queue by posting a runnable on that queue.
I often end up using a separate fragment that it retaininstance(true)
that has a ResultReceiver
. So i pass on that result receiver to my jobs and handle callbacks in its onReceive (often as a router for other receivers). But that might be a bit more work than it is worth if you are using async tasks.