I have an Android app and it has been recently crashing building some Fragments. This doesn't happen always, just occasionally.
This is the typical crash log:
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mycompany.myapp./com.mycompany.myapp..ui.activities.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.mycompany.myapp..l.a.a1: could not find Fragment constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3534)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3689)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2239)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7822)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)
So far I was building the fragments this way:
String fragmentName = MyFragment.class.getName()
Fragment fr = Fragment.instantiate(this, fragmentName);
final FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frame_content, fr, fragmentName);
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
ft.commit();
fm.executePendingTransactions();
And this crash never happened until a couple of months ago. I don't know if I changed something or it's related to Android version (I'm compiling with SDK 29).
Trying to solve the problem I changed the way I build the fragments to use FragmentFactory:
String fragmentName = MyFragment.class.getName()
final FragmentManager fm = getSupportFragmentManager();
FragmentFactory ff = fm.getFragmentFactory();
Fragment fr = ff.instantiate(getClassLoader(), fragmentName);
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frame_content, fr, fragmentName);
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
ft.commit();
fm.executePendingTransactions();
But the crash is still happening.
Taking into account the log it seems like the fragment class name is obfuscate or something like that and Android is not able to deobfuscate it. In case it's important I have this gradle configuration:
buildTypes {
release {
minifyEnabled true
firebaseCrashlytics {
mappingFileUploadEnabled true
}
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
And my Proguard-rules.pro file includes this:
-keepattributes SourceFile,LineNumberTable # Keep file names and line numbers.
-keep public class * extends java.lang.Exception # Optional: Keep custom exceptions.
Don't initiate your Fragments with the "instantiate" function, to fix the error look at this answer https://stackoverflow.com/a/62931666/5313283