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):
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
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.