Android InstantiationException With Fragment (It Is Public)
Asked Answered
S

3

19

I have a Fragment (it is not an inner class, and it does not have any constructor whatsoever)

public class PreferenceListFragment extends ListFragment implements OnClickListener

I'm getting this crash report on the Android Developer Console:

java.lang.RuntimeException: Unable to start activity 
ComponentInfo{com.redacted.redacted/com.redacted.redacted.PreferenceActivity}: 
android.support.v4.app.Fragment$InstantiationException: 
Unable to instantiate fragment com.redacted.redacted.PreferenceListFragment$3:
make sure class name exists, is public, and has an empty constructor that is
public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1750)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1766)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2960)
at android.app.ActivityThread.access$1600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:945)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3818)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.support.v4.app.Fragment$InstantiationException: 
Unable to instantiate fragment com.redacted.redacted.PreferenceListFragment$3: 
make sure class name exists, is public, and has an empty constructor that
is public
at android.support.v4.app.Fragment.instantiate(Fragment.java:399)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1760)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:200)
at com.redacted.redacted.PreferenceActivity.onCreate(PreferenceActivity.java:37)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1710)
... 12 more
Caused by: java.lang.InstantiationException: 
com.redacted.redacted.PreferenceListFragment$3
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1409)
at android.support.v4.app.Fragment.instantiate(Fragment.java:388)
... 18 more

I am unable to replicate this on any of my test devices.

Here's the PreferenceActivity.onCreate where the exception is occurring:

public class PreferenceActivity extends FragmentActivity{

    PreferenceListFragment frag;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.preference);

        frag = (PreferenceListFragment) getSupportFragmentManager().
                findFragmentById(R.id.preference_list_frag);
        frag.setState(AlarmPreferenceState.Selected);
        frag.setIsTwoPane(false);
    }

    .
    .
    .
}

And here is R.layout.preference:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment class="com.redacted.redacted.PreferenceListFragment"
          android:id="@+id/preference_list_frag"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>

</FrameLayout>

Anyone know why I might be getting this exception, and/or how to reproduce it?

Splenomegaly answered 25/12, 2012 at 13:36 Comment(11)
I didn't fully understand this from the question: does your PreferenceListFragment class have any other constructors besides a no arguments one?Contemporaneous
It has no constructor....a while back I was having another problem with a Fragment and someone on SO said not to have any constructor in a FragmentSplenomegaly
Is the PreferenceListFragment class an inner class in some other class? If yes then make it static, otherwise you'll get that exception.Contemporaneous
@Luksprog updated the question to reflect that it is not an inner class. I am also unable to reproduce this (I got the exception from the developer console)Splenomegaly
When you say it has no constructor, do you mean not even an empty one? See here.Astraea
Judging by the stacktrace you're using anonymous fragment classes of PreferenceListFragment and Android can't instantiate them. If this is true than you should avoid those anonymous classes.Contemporaneous
@Astraea there are no constructors whatsoeverSplenomegaly
@Luksprog As far as I know, I'm inflating them from XML. It works on every device I've tried it on. The only reason I know about it is because it showed up as reported on the developer console. I just wanna make sure it's not some bug that rarely pops up. Even worse than that would be if it were non-deterministic.Splenomegaly
Could you share your project file structure or Manifest file ?Vermiculite
@Vermiculite the project file structure is the standard Eclipse structure for an Android project. What part of the Manifest would you like to see?Splenomegaly
ohk! just the package declaration and if you could share the stuff you have written in PreferenceListFragment. Except for that I couldn't find anything wrong in your project.Vermiculite
C
21

You MUST have an empty public constructor. Whoever told you to not have a fragment constructor steered you in the wrong direction.

What they might have told you, is to not have a constructor that accepts arguments, since those may not be called by the system when re-creating the fragments. In that case, use the example in the docs to supply arguments to your fragment.

Quoted from the docs :

All subclasses of Fragment must include a public empty constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it. If the empty constructor is not available, a runtime exception will occur in some cases during state restore. [1], [2]

[1] : https://developer.android.com/reference/android/app/Fragment.html

[2] : https://developer.android.com/reference/android/app/Fragment.html#Fragment()

Choriocarcinoma answered 5/4, 2013 at 9:53 Comment(2)
I'll try adding one and see if any more errors pop up. Thanks!Splenomegaly
The default constructor is always present, unless we make it private.Isleana
B
3

CHECK YOUR PROGUARD RULES

The strange thing in my case was, this error popped only in the release build and not in the debug build.

The issue was, I was using a FragmentContainerView to hold the Fragment and mentioned the Fragment class name in the XML itself, like this

<androidx.fragment.app.FragmentContainerView
                android:id="@+id/f_navigation_fragment"
                class="com.example.MyFragmentClass"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

This worked fine in the Debug build (without Proguard Obfuscation) but in the Release build (with Proguard Obfuscation) the actual Fragment class was Obfuscated and hence the XML was unable to locate it leading to OP's error.

Please refer this link for additional references.

Burnett answered 30/6, 2020 at 7:5 Comment(0)
K
0

I got this error when I accidentally tried to navigate to an abstract Fragment class.

Kasiekask answered 21/10, 2020 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.