0

Apologies for the long title. My problem is as follows: I use a DialogFragment to prevent AlertDialogs from being dismissed on rotation (similar to the answer here: Prevent dialog dismissal on screen rotation in Android).

Now, I run some task in the background that might take some seconds. I want to show a progressdialog to tell the user what is going on. Once the task is done, the ProgressDialog should be dismissed from the finished-method in the AsyncTask.

Like in the link above, I use a DialogFragment to create a Dialog. The dialog is preserved on rotation (which is good). Yet, once my task is done AND the screen was rotated, I cannot dismiss the dialog.

Here are the strategies that I have tried (both methods work if the screen wasn't rotated):

  • Calling "dismiss()" of the DialogFragment. After screen rotation, this causes a crash java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference android.app.DialogFragment.dismissInternal(DialogFragment.java:296) android.app.DialogFragment.dismiss(DialogFragment.java:267)
  • Calling some internal method that calls "getDialog().dismiss()": getDialog() returns always null (after rotation) although the dialog is shown.

Could someone lead me into the right direction?

EDIT: Here is some code

Inside the activity, I simply create a TaskFragment that does some background work:

public class MainActivity extends AppCompatActivity {

    private TaskFragment ft;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ft = (TaskFragment) getFragmentManager().findFragmentByTag("task");

        if(ft == null) {
            // create new
            ft = TaskFragment.newInstance();

            FragmentTransaction transaction = getFragmentManager().beginTransaction();
            transaction.add(ft, "task");
            transaction.commit();
        }
    }
}

Inside the TaskFragment I run an AsyncTask. In onPreExecute I show a ProgressDialog, in onPostExecute I dismiss it:

public class TaskFragment extends Fragment {

    public static TaskFragment newInstance() {
        return new TaskFragment();
    }

    public TaskFragment() {}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setRetainInstance(true);

        // Run a background task and show a dialog
        new AsyncTask<Void, Void, Void>() {
            MyDialogFragment ft;

            @Override
            protected void onPreExecute() {
                // show progress dialog
                ft = MyDialogFragment.newInstance();
                ft.show(getActivity().getFragmentManager(), "dialog");
            }

            @Override
            protected Void doInBackground(Void...params) {
                try {
                    // Do some work...
                    Thread.sleep(5000);
                } catch (InterruptedException ignored) {}

                return null;
            }

            @Override
            protected void onPostExecute(Void p) {
                // remove progress dialog
                ft.dismiss();
            }
        }.execute();
    }
}

The DialogFragment is just the following:

public class MyDialogFragment extends DialogFragment {
    public static MyDialogFragment newInstance() {
        MyDialogFragment fragment = new MyDialogFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setCancelable(false);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        ProgressDialog dialog = new ProgressDialog(getActivity());

        dialog.setIndeterminate(true);

        dialog.setTitle("Hello World");

        return dialog;
    }
}

Thanks and best regards, Karl

Community
  • 1
  • 1
Searles
  • 1,447
  • 1
  • 11
  • 26
  • 1
    Where is the minimal code? ... – Selvin Feb 09 '17 at 11:06
  • anyway: https://gist.github.com/SelvinPL/4230c0b6b45fb69a8ed856a4fa43dec3 – Selvin Feb 09 '17 at 11:15
  • Just added minimal code. Thanks for the code, I think it points me into the right direction (I thought that DialogFragments are retained and not recreated after rotation). Will check. Thanks (and sorry for not adding a minimal code example in the first place. – Searles Feb 09 '17 at 16:25
  • As you can see in my link it rather DialogFragment shoud contain "job" fragment – Selvin Feb 09 '17 at 16:27
  • My JobFragment is much bigger, I just need the progress dialog to provide feedback that some initialization code takes a bit longer than expected. In fact, I check after 1 second whether the initialization is done, and only then show the dialog. – Searles Feb 16 '17 at 08:14

1 Answers1

0

Thanks Selvin, your code and comment pointed me into the correct direction.

The problem is that I have to freshly fetch the Fragment when I dismiss it. Additionally, since the Activity might not be active when the dialog is dismissed I need to allow stateloss when I dismiss it to avoid a NullPointerException. Thus, I update the AsyncTask to the following and it works fine.

        // Run a background task and show a dialog
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            // show progress dialog
            MyDialogFragment ft = MyDialogFragment.newInstance();
            ft.show(getActivity().getFragmentManager(), "dialog");
        }

        @Override
        protected Void doInBackground(Void...params) {
            try {
                // Do some work...
                Thread.sleep(5000);
            } catch (InterruptedException ignored) {}

            return null;
        }

        @Override
        protected void onPostExecute(Void p) {
            MyDialogFragment ft = 
                (MyDialogFragment) getFragmentManager()
                .findFragmentByTag("dialog");

            // remove progress dialog
            ft.dismissAllowingStateloss();
        }
    }.execute();

Again thanks for your help.

Searles
  • 1,447
  • 1
  • 11
  • 26