Dialog rollback appears again when application resumes

Hi, I am developing an application that uses maps.

I am using Fragment Activity and a fragment called Fragment-A.

In Fragment-A there is a button, when you click this button, a fragment of the dialog opens, a map with a certain location obtained earlier from the server is displayed.

Say this piece of dialogue is DialogFragment-B.

It has a button to close, a button to go to the Google Maps app to get directions.

If the user goes to DialogFragment-B and returns to fragment-A by pressing the close button, everything works fine.

But if the user presses the "Back" button, the existing fragment of the dialog closes normally, and the application functions normally.

But if the user pressed the home button or received a phone call, and onResume is called even if DialogFragment-B is fired earlier, it appears again and pressing the button closes the application with an exception with a null pointer

Here is my code to open DialogFragment-B.

FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); android.app.Fragment prev = fm.findFragmentByTag(MY_MAP); if (prev != null) { ft.remove(prev); } MyMapFragmentDialog newFragment = MyMapFragmentDialog .newInstance(eachPost); newFragment.show(ft, MY_MAP); 

In DialogFragment-B, when I click the close button, I call MyMapFragmentDialog.this.dismiss ();

Please, if someone ran into this problem and won, guide me through.

+6
source share
2 answers

I had the same problem and solved it, making sure I call super.onDismiss(dialog) in the onDismiss method of my DialogFragment subclass.

+10
source

Update: Kalina's answer is a more elegant and simpler solution - as I understood later!

I encountered the same problem in one of my applications and did not find the answer anywhere, went through the source code of the DialogFragment class, which is available at:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/DialogFragment.java#DialogFragment.onDismiss%28android.content.DialogInterface% 29th

and there, I found the probable reason written in the comment in the source of the onDismiss dialog (DialogInterface):

 // Note: we need to use allowStateLoss, because the dialog // dispatches this asynchronously so we can receive the call // after the activity is paused. Worst case, when the user comes // back to the activity they see the dialog again. 

What I understood from this is that the dismissal is not saved in the state of the instance, and when the action is resumed, it quickly displays it again as part of restoring the state of the instance - provided that the fragment was never fired. Being an asynchronous event, there is no safe way to make a dismissal without risk.

 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 

exception and subsequent failure, which is probably why the authors of this class decided to do it this way.

The solution that worked for me was to separately monitor the state of the Dialog dialog box:

  • Saving it in a class variable (here called "dialogue")
  • Dialog override onDismiss (DialogInterface) and
  • Setting the boolean dialogDismissed flag to true

-

 @Override public void onDismiss(DialogInterface dialog) { // dialogDismissed is a Class level variable in the containing Activity, // must be set to false each time the DialogFragment is shown dialogDismissed = true; } 
  • Note: if DialogFragment is a separate class, then for this you need to call a method in Activity, which can be called from onDismiss, possibly by setting the interface

  • Then this flag should be marked in the onResume () action, and forced rejection (after checking that the dialog is not zero):

-

 @Override public void onResume() { super.onResume(); //... if (dialogDismissed && dialog != null) { dialog.dismiss(); } } 
+2
source

Source: https://habr.com/ru/post/979969/


All Articles