Calling DialogFragment from Activity resulting in "IllegalStateException: fragment not attached to Activity"

android, android-fragments

Solution

You could use a static class that uses the application context for the callback.

Activities and Fragments are ephemeral, so it is dangerous to rely on them to be in a good state after an asynchronous callback.

Problem

I have an Activity that has a Fragment, and I need to show a DialogFragment (which is declared public and static inside the fragment) for logging the user out. In this dialog I need to make a server request and when it's done, the dialog must be dismissed. The problem here is that when the server request arrives, I get the error "IllegalStateException: fragment not attached to Activity" Is there a way to do overcome this problem? EDIT: This is the `logcat` output: ``` E/AndroidRuntime(13849): java.lang.IllegalStateException: Fragment LogoutDialogFragment{4256be70} not attached to Activity E/AndroidRuntime(13849): at android.support.v4.app.Fragment.startActivity(Fragment.java:836) E/AndroidRuntime(13849): at nl.emte.merchant.ui.EmteActivity$LogoutDialogFragment$1$1.onDataLoad(EmteActivity.java:328) E/AndroidRuntime(13849): at nl.emte.merchant.api.EmteApiManager$5.onPostExecute(EmteApiManager.java:212) ``` And this is the code of the `LogOutFragment` which is the `DialogFragment` that allows users to log out: ``` public static class LogoutDialogFragment extends SherlockDialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setCancelable(true); builder.setMessage(R.string.logout_screen_description); builder.setPositiveButton(R.string.logout_positive_button_lbl, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); EmteApiManager.getInstance().doLogout(new DataLoadListner() { @Override public void onError(Object errorMessage) { } @Override public void onDataLoad(Object result) { Intent intent = new Intent( IntentActions.ACTION_LOGIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }); } }).setNegativeButton(R.string.logout_negative_button_lbl, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); return builder.create(); } } ``` Thanks in advance!

Original source