Android – DialogFragment Orientation Change Crash with getActivity()

androidorientation

I'm currently having some problems with DialogFragments.
I'm using the latest v.4 support packages (Revision 8 I believe)
My problem is, that if the orientation of my phone changes while the dialog is open, the application begins acting wierd.

Currently my application works like this:
There is a FragmentActivity, it calls a Fragment.
This Fragment then calls a DialogFragment (via getActivity().getSupportFragmentManager().

If the orientation changes while the dialog is open, the getActivity() in the Fragment = null.
This causes a problem if I want to finish the Activity etc.

To cause this you open the dialog, change the orientation and press a button. Only after you press the button it crashes

My DialogFragment is called AlertDialogFragment:

public class AlertDialogFragment extends DialogFragment {
private static Builder mBuilder;
private static DialogInterface.OnClickListener mListener;

public static AlertDialogFragment newInstance(Context context, DialogInterface.OnClickListener listener) {
    mBuilder = new AlertDialog.Builder(context);
    mListener = listener;       
    return new AlertDialogFragment();
}

//... some functions to set Icons etc

public void setButton(int whichButton, CharSequence buttonText) {
    final DialogInterface.OnClickListener listener = mListener == null ? null : mListener;      
    mBuilder.setPositiveButton(buttonText, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                listener.onClick(dialog, whichButton);
            }
    });
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return mBuilder.create();
}
}

This is the Fragment:

public class TestBedFragment extends Fragment implements DialogInterface.OnClickListener   {
// onCreateView Stuff  

private void showCrashDialog() {
    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
    AlertDialogFragment newDialog = AlertDialogFragment.newInstance(getActivity(), this);
    newDialog.setTitle("Test");     
    newDialog.setIcon(android.R.drawable.ic_dialog_alert);
    newDialog.setMessage("Testing testing testing... 1, 2, 3... Just press Ok.");
    newDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Ok");
    newDialog.show(ft, "dialog");

    // Cause the problem. Simulate the user turning the screen
    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

@Override
public void onClick(DialogInterface dialog, int which) {

    /*
     * hexnumber = a hex number
     * Normally equals: TestBedFragment{hexnumber #0 id=hexnumber}
     * With crash equals: TestBedFragment{hexnumber}
     */
    Log.e("TestBedFragment", "this = " + this);

    /*
     * hexnumber = a hex number
     * Normally equals: com.example.TestBed.TestBedActivity@hexnumber
     * With crash equals: null
     */
    Log.e("TestBedFragment", "getActivity() = " + getActivity()); // Will equal null... ???

    getActivity().finish();
}
}

I'm not too sure whats causing this? Sorry if its a stupid question. I have read in other places about 'Windows Leaking', yet I haven't seen any mention of that stuff in logcat.

Can anyone help me 🙂 Its greatly appreciated

Thanks

Best Answer

You have to understand Activity life cycle. Everytime you rotate the device, the activity is recreated. It means a new instance of the class is executing.

What happens in your code is that, after a rotation, the listener calls getActivity on a previous dialog instance, referring to the previous activity. But this activity is not valid any more, it has been "destroyed" after the rotation and a new one appeared.

You call to getActivity is not valid anymore.

Can't you close your open dialog during fragment onDestroy method ?

Related Topic