java.lang.NoSuchMethodException for onCreate
The activity is being restored from an instance state bundle. Part of the restore operation is recreating its fragments.
Your activity has a fragment and the fragment class does not have a 0-arg constructor required by the framework.
After some search i finally fix the issue. You have to check 3 things.
- You should have a 0-arg constructor in the fragment, best practice is to do something like bellow
- If you are using callback in the caller, you have to check if getContext is
null
or not (otherwise you will get a NullPointerException) - Don't forget to test the case when the screen orientation change, this will allow you to reproduce some potential issue due to restoring fragment state
Sample code example :
public class MyDialogFragment extends DialogFragment{
private String id;
public static MyDialogFragment newInstance(String id) {
MyDialogFragment f = new MyDialogFragment ();
Bundle args = new Bundle();
if(id!= null){
args.putString("id", id);
}
f.setArguments(args);
return f;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
id= savedInstanceState.getString("id");
}
}
}
I'm having the same issue. The other answers did not help.
For me, it looks like it is Proguard. That explains why it only happens in production/release builds and why I have been unable to reproduce it when debugging.
If you're having OP's issue, try the following:
- Build the obfuscated .apk. I used the signed one, that I publish to the app stores...
- Enable "Don't Keep Activities" in your device's developer options.
- Install the .apk in your device and open the Activity that crashes and contains the Fragment.
- Leave your app (Minimize / Home button / ...) and re-open it from the recent apps menu.
Does it crash? Then try it with the un-obfuscated debug build. If it doesn't then it's probably Proguard.
To fix it I did the following:
- Create a proguard-rules.pro file in your app module's root folder.
- Add -keep class * extends androidx.fragment.app.Fragment{} to that file.
- Then, in the app's build.gradle,
add:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
See Yaroslav Mytkalyk's answer here: Fragment Instantiation crash, which helped me solve this, although it's a bit old and outdated by now (e.g. "runProguard true" is obsolete).
At least now it doesn't crash when I do the steps above.
PS: I did this in conjunction with adding the 0-arg constructors to my fragments, as mentioned in other answers, since that was my first fixing attempt. I believe that Proguard alone was the issue and that it isn't necessary to add said constructors, but I cannot test that hypothesis now.
My Activity had a FragmentPagerAdapter
that was using the deperecated constructor.
I changed
class MyPagerAdapter(
fragmentManager: FragmentManager,
private val myActivity: MyActivity
) : FragmentPagerAdapter(fragmentManager) // DEPRECATED
to
class MyPagerAdapter(
fragmentManager: FragmentManager,
private val myActivity: MyActivity
) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
Seem to have fixed the problem