Eugene
Eugene

Reputation: 60184

InstantiationException on Orientation Change when DialogFragment is on the top

I have a DialogFragment defined as inner class in my Fragment class. On Orientation Change even the following exception is poped up:

 Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment my.package.fragments.ImportFragment$FailedImportDialog: make sure class name exists, is public, and has an empty constructor that is public
        at android.app.Fragment.instantiate(Fragment.java:585)
        at android.app.FragmentState.instantiate(Fragment.java:96)
        at android.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1682)
        at android.app.Activity.onCreate(Activity.java:861)
        at my.package.activities.ImportActivity.onCreate(ImportActivity.java:8)
        at android.app.Activity.performCreate(Activity.java:4465)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
        ... 12 more
        Caused by: java.lang.InstantiationException: can't instantiate class my.package.fragments.ImportFragment$FailedImportDialog; no empty constructor
        at java.lang.Class.newInstanceImpl(Native Method)
        at java.lang.Class.newInstance(Class.java:1319)
        at android.app.Fragment.instantiate(Fragment.java:574)

But I do have public constructor:

class FailedImportDialog extends DialogFragment {

        private EditText edtPassword;
        private Button button;

        public FailedImportDialog() { // Here it is!
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.another_password_dialog, container, false);
            edtPassword = (EditText) v.findViewById(R.id.another_password_dialog_et_password);

            getDialog().setTitle(R.string.failed_to_decrypt);

            Button button = (Button) v.findViewById(R.id.another_password_dialog_btn_ok);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

            });

            return v;

    }
}

Here is xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical"
              android:padding="10dp">

    <TextView android:id="@+id/another_password_dialog_tv_text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/what_password_did_you_use">
    </TextView>

    <EditText android:id="@+id/another_password_dialog_et_password"
              android:layout_height="wrap_content"
              android:layout_width="match_parent"
              android:inputType="textPassword">
        <requestFocus>
        </requestFocus>
    </EditText>

    <Button android:id="@+id/another_password_dialog_btn_ok"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="OK">
    </Button>

</LinearLayout>

Do you guys know why this exception happens? Thank you!

UPDATE: If I move a class to a separate file there is no such an exception, everything goes smoothly. So the question is - why this exception happens when DialogFragment is an inner class?

Upvotes: 10

Views: 2541

Answers (3)

Thomas Gatt
Thomas Gatt

Reputation: 869

Calling setRetainInstance(true) will cause the FragmentManager to save your actual Fragment instance. Instead of destroying and recreating the Fragment, it will just pass the same one along to the new Activity.

Upvotes: 7

gsb
gsb

Reputation: 5640

try making the inner class static:

public static class FailedImportDialog extends DialogFragment 

I will post more explanation about this in a while. In the meantime, try this and let me know if it works.

Upvotes: 5

tolgap
tolgap

Reputation: 9778

Define your inner class like this:

public class FailedImportDialog extends DialogFragment {
....
}

With the public notation.

Because, this is what your LogCat says:

Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment
my.package.fragments.ImportFragment$FailedImportDialog: make sure class name exists 
is public, and has an empty constructor that is public

Upvotes: 0

Related Questions