Closed metinvio closed 1 year ago
@metinvio hello, glad to hear simple-stack is working well! Based on your stack trace (q2.v1
) being obfuscated, I would expect that you either have Fragments with multiple constructors (you should only have no argument constructor on a fragment), or the Fragment's constructor is removed by R8 in release mode.
You could try these proguard-rules.pro additions:
-keepclassmembers public class * extends android.support.v4.app.Fragment {
public <init>(...);
}
-keepclassmembers public class * androidx.fragment.app.Fragment {
public <init>(...);
}
In general, I expect this to be a process death crash caused by having non-empty fragment constructor. You should always use empty constructor + pass args with setArguments()
(with simple-stack and DefaultFragmentKey
/DefaultFragmentStateChanger
, this already happens and passes the @Parcelize data class YourKey(..
as an argument. If you extend from KeyedFragment
then you can use getKey()
, if you don't then requireArguments().getParcelable(DefaultFragmentKey.KEY_ARGS)
.)
@Zhuinden thank you for the quick response. I doubt that this is caused by Proguard. Because it also happens in debug mode where proguard is disabled. But I think the second part of your answer is more likely the cause. I will check that and will let you know - thanks a lot đ
@metinvio Did you succeed in figuring out the cause?
Hi @Zhuinden , no unfortunately it's still the same. I changed all my Fragment to this:
class MyFragment: Fragment() {
...
companion object{
fun newInstance(name : String) : MyFragment {
val args = Bundle()
args.putSerializable(ARG_NAME, name)
val fragment = MyFragment()
fragment.arguments = args
return fragment
}
}
}
and I still get crash reports like following:
java.lang.NoSuchMethodException - o2.u2.
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxxxxxxx/com.xxxxxxxxx.activities.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment o2.w2: could not find Fragment constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
In RootScreen I'm calling them like:
override fun bindServices(serviceBinder: ServiceBinder) {
with(serviceBinder) {
add(FragmentStackHost(Screen1()), SCREEN1_STACK)
add(FragmentStackHost(Screen2()), SCREEN2_STACK)
add(FragmentStackHost(Screen3()), SCREEN3_STACK)
add(FragmentStackHost(Screen4)), SCREEN4_STACK)
add(FragmentStackHost(Screen5()), SCREEN5_STACK)
}
}
and inside NavigationKeys.kt like:
@Parcelize
class Screen1 : DefaultFragmentKey() {
override fun instantiateFragment(): Fragment = MyFragment.newInstance()
}
Theoretically if you have a noarg constructor that you call from code, then it can't be removed by Proguard. It would be nice to know what o2.u2.
and o2.w2
is based on your Proguard mapping
file (it's in the build outputs) so that you can troubleshoot more.
Btw, make sure your keys are data class
(or data object
) as per the readme.
@metinvio did you ever figure this out?
What is o2.w2
in your Proguard mapping, is it YOUR class? Maybe it's something like MapFragment used from <fragment
and Proguard actually doesn't keep its constructor.
Sorry for the late reply, I haven't had a chance to check it out yet. Ok, thanks to your advice regarding pro guard and mapping.txt, I was able to see where the crashes happen originally. To summarize: After reading you answers again carefully, I understood it in detail. The main problem was the constructor. I have removed them in all my fragments and added a companion object with a newInstance-Method. No crashes anymore! Thank you my friend, you saved me a lot of trouble - again! đâ¤ď¸
First of all thank you very much for this great sdk. It simplifies a lot of things and saves us a lot of time đ.
But I have a problem I'm struggling with since I'm using NavHost. I was hoping that simple-stack would solve the problem, but it still happens. I know it's not the SDK, but maybe someone here knows what I'm doing wrong.
It always happens when the app comes to the foreground after a long time, or when the app tries to restart after a crash. And it happens randomly for every fragment I have in my BottomNavigation. Sometimes it's the first tab, other times it's the third tab (/fragment). Sometimes it's
could not find Fragment constructor
and sometimesError inflating class fragment
. It also happens when you rotate the phone. But fortunately our app is portrait mode only. This is the stacktrace I get on Crashlytics:or