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.