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?

Eliezer
  • 7,209
  • 12
  • 56
  • 103
  • I didn't fully understand this from the question: does your `PreferenceListFragment` class have any other constructors besides a no arguments one? – user Dec 25 '12 at 13:58
  • 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 `Fragment` – Eliezer Dec 25 '12 at 14:29
  • 1
    Is the `PreferenceListFragment` class an inner class in some other class? If yes then make it `static`, otherwise you'll get that exception. – user Dec 25 '12 at 14:43
  • @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) – Eliezer Dec 25 '12 at 15:35
  • When you say it has no constructor, do you mean not even an empty one? See [here](http://stackoverflow.com/questions/10450348/do-fragments-really-need-an-empty-constructor). – Geobits Dec 25 '12 at 15:38
  • 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. – user Dec 25 '12 at 16:11
  • @Geobits there are no constructors whatsoever – Eliezer Dec 25 '12 at 16:35
  • @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. – Eliezer Dec 25 '12 at 16:37
  • Could you share your project file structure or Manifest file ? – VenoM Mar 15 '13 at 11:48
  • @VenoM the project file structure is the standard Eclipse structure for an Android project. What part of the Manifest would you like to see? – Eliezer Mar 15 '13 at 19:27
  • 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. – VenoM Mar 18 '13 at 04:57

3 Answers3

20

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()

f2prateek
  • 2,034
  • 2
  • 20
  • 26
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.

iCantC
  • 2,852
  • 1
  • 19
  • 34
0

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

Zezi Reeds
  • 1,286
  • 1
  • 16
  • 29