Java – fragment instantiation crashes

fragment instantiation crashes… here is a solution to the problem.

fragment instantiation crashes

Some of my users are experiencing crashes that are shown in the Google Play Developer Console crash report:

Unable to start Activity ComponentInfo{com.havens1515.autorespond

/com.havens1515.autorespond.SettingsMenuNew}:android.app.Fragment$InstantiationException: Unable to instantiate fragment com.havens1515.autorespond.NotificationOptions: Ensures that the class name exists, is public, and has a public empty constructor

The user said this happens when opening any settings menu in SettingsMenuNew mentioned in the error above, but my phone is not experiencing a crash. SettingsMenuNew is a PreferenceActivity, and all submenus are PreferenceFragments

Each PreferenceFragment has an empty constructor, I don’t know what else is wrong. I’ve also seen in other people’s issues that it requires the newInstance method, but I don’t think I really need it if I don’t put any other arguments in the fragment.

Here is some code that shows these methods:

public class NotificationOptions extends PreferenceFragment
{
    public NotificationOptions()
    {

}

public static NotificationOptions newInstance(int title, String message)
    {
        NotificationOptions f = new NotificationOptions();
        return f;
    }
    ...
}

Solution

This can happen due to the obfuscator removing your fragment.

To reproduce, build the obfuscated APK, enable “Do not keep activities” in developer options, open the activity that contains the crashed fragment. Minimize the Home button and restore apps from recently used apps.

To merge the obfuscator configuration with the default configuration and your configuration in ADT, you should specify it in project.properties

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

If you are using the Gradle build system

buildTypes {
    debug {
        runProguard false
    }

release {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
}

And proguard-project.txt should contain at least these rules

-keep public class * extends android.preference.PreferenceFragment

Support fragments if you use

-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.support.v4.app.FragmentActivity

Don’t forget that ${sdk.dir}/tools/proguard/proguard-android.txt already contains some rules, so add only the missing ones according to your needs.

Related Problems and Solutions