Reputation: 60184
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
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
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
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