flutter_stripe
flutter_stripe copied to clipboard
After changing FlutterActivity to FlutterFragmentActivity in PlayStore shows app crash logs
Describe the bug As per documentation after changing FlutterActivity to FlutterFragmentActivity app crash in release mode but it is not crashing for all the device and not able to reproduce on my end but it shows in crashlytics and PlayStore console.
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{*******}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment yl.o0: could not find Fragment constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3006)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3084)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1781)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:210)
at android.app.ActivityThread.main(ActivityThread.java:7080)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:863)
Caused by androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment yl.o0: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:630)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$2.instantiate(FragmentManager.java:448)
at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:81)
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:2410)
at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:2584)
at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:116)
at androidx.fragment.app.FragmentActivity.lambda$init$1(FragmentActivity.java:128)
at androidx.fragment.app.FragmentActivity.$r8$lambda$QtiQ2ZI3e38UkO1_xuJ8vE_JZj4(FragmentActivity.java)
at androidx.fragment.app.FragmentActivity$$InternalSyntheticLambda$0$cef12c4fb802c6ea87b1fbddce076644080634cb6e3f7fb823e201a9f4f7f1ec$1.onContextAvailable(FragmentActivity.java:2)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:320)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:249)
at io.flutter.embedding.android.FlutterFragmentActivity.onCreate(FlutterFragmentActivity.java:279)
at android.app.Activity.performCreate(Activity.java:7314)
at android.app.Activity.performCreate(Activity.java:7305)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2959)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3084)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1781)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:210)
at android.app.ActivityThread.main(ActivityThread.java:7080)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:863)
Caused by java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor0(Class.java:2320)
at java.lang.Class.getConstructor(Class.java:1725)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:615)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$2.instantiate(FragmentManager.java:448)
at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:81)
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:2410)
at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:2584)
at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:116)
at androidx.fragment.app.FragmentActivity.lambda$init$1(FragmentActivity.java:128)
at androidx.fragment.app.FragmentActivity.$r8$lambda$QtiQ2ZI3e38UkO1_xuJ8vE_JZj4(FragmentActivity.java)
at androidx.fragment.app.FragmentActivity$$InternalSyntheticLambda$0$cef12c4fb802c6ea87b1fbddce076644080634cb6e3f7fb823e201a9f4f7f1ec$1.onContextAvailable(FragmentActivity.java:2)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:320)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:249)
at io.flutter.embedding.android.FlutterFragmentActivity.onCreate(FlutterFragmentActivity.java:279)
at android.app.Activity.performCreate(Activity.java:7314)
at android.app.Activity.performCreate(Activity.java:7305)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2959)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3084)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1781)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:210)
at android.app.ActivityThread.main(ActivityThread.java:7080)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:863)
Smartphone / tablet
- Device: Samsung Device
- OS: Android 12, 11, 10
- Package version: 4.0.0
- Flutter version
Flutter 3.0.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision f1875d570e (4 months ago) • 2022-07-13 11:24:16 -0700
Engine • revision e85ea0e79c
Tools • Dart 2.17.6 • DevTools 2.12.2
Additional context
This was not causing any issue when it was FlutterActivity but after changed to FlutterFragmentActivity
it starts crash.
Can you try to upgrade to the latest version 6.0.0 and try if it happens there? I do not see any code from our repo crashing in the logs.
We have the same issue, with version 6.0.0.
Anyone knows the cause of this or how to fix?
@remonh87 I have upgraded to 6.0.0 and still showing crash in Crashlytics and PlayStore.
I think this is related to this https://github.com/flutter/flutter/issues/114971. This package is also using the FlutterFragmentActivity and found crash.
On version 7.0.0 here and still happening. Both in PaymentSheetFragment and GooglePayFragment.
It looks like these fragments don't have a no-arg constructor, which causes the crash when the app is resumed and fragments re-created.
Steps to reproduce (for us at least):
- Enable "Don't keep activities" in Developer Options.
- After calling
Stripe.instance.initPaymentSheet(...)
somewhere, put the app in background. - Re-enter the app. Result: The app crashes after splash with the following stacktrace:
E/AndroidRuntime( 1575): java.lang.RuntimeException: Unable to start activity ...
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.reactnativestripesdk.PaymentSheetFragment: could not find Fragment constructor
E/AndroidRuntime( 1575): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166)
E/AndroidRuntime( 1575): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
E/AndroidRuntime( 1575): at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
E/AndroidRuntime( 1575): at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
E/AndroidRuntime( 1575): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
E/AndroidRuntime( 1575): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
E/AndroidRuntime( 1575): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 1575): at android.os.Looper.loopOnce(Looper.java:226)
E/AndroidRuntime( 1575): at android.os.Looper.loop(Looper.java:313)
E/AndroidRuntime( 1575): at android.app.ActivityThread.main(ActivityThread.java:8741)
E/AndroidRuntime( 1575): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 1575): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
E/AndroidRuntime( 1575): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
E/AndroidRuntime( 1575): Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.reactnativestripesdk.PaymentSheetFragment: could not find Fragment constructor
E/AndroidRuntime( 1575): at androidx.fragment.app.Fragment.instantiate(Fragment.java:678)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:507)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:81)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:2505)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:2665)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:117)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentActivity.lambda$init$3$androidx-fragment-app-FragmentActivity(FragmentActivity.java:140)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentActivity$$ExternalSyntheticLambda0.onContextAvailable(Unknown Source:2)
E/AndroidRuntime( 1575): at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
E/AndroidRuntime( 1575): at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:362)
E/AndroidRuntime( 1575): at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:217)
E/AndroidRuntime( 1575): at io.flutter.embedding.android.FlutterFragmentActivity.onCreate(FlutterFragmentActivity.java:279)
E/AndroidRuntime( 1575): ... 15 more
E/AndroidRuntime( 1575): Caused by: java.lang.NoSuchMethodException: com.reactnativestripesdk.PaymentSheetFragment.<init> []
E/AndroidRuntime( 1575): at java.lang.Class.getConstructor0(Class.java:2363)
E/AndroidRuntime( 1575): at java.lang.Class.getConstructor(Class.java:1759)
E/AndroidRuntime( 1575): at androidx.fragment.app.Fragment.instantiate(Fragment.java:663)
E/AndroidRuntime( 1575): ... 30 more
The GooglePayFragment crash is almost identical:
- Enable "Don't keep activities" in Developer Options.
- After calling showing the Google Pay sheet somewhere, exit it and put the app in background.
- Re-enter the app.
E/AndroidRuntime( 5656): java.lang.RuntimeException: Unable to start activity ...
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.reactnativestripesdk.GooglePayFragment: could not find Fragment constructor
E/AndroidRuntime( 5656): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166)
E/AndroidRuntime( 5656): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
E/AndroidRuntime( 5656): at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
E/AndroidRuntime( 5656): at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
E/AndroidRuntime( 5656): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
E/AndroidRuntime( 5656): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
E/AndroidRuntime( 5656): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 5656): at android.os.Looper.loopOnce(Looper.java:226)
E/AndroidRuntime( 5656): at android.os.Looper.loop(Looper.java:313)
E/AndroidRuntime( 5656): at android.app.ActivityThread.main(ActivityThread.java:8741)
E/AndroidRuntime( 5656): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5656): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
E/AndroidRuntime( 5656): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
E/AndroidRuntime( 5656): Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.reactnativestripesdk.GooglePayFragment: could not find Fragment constructor
E/AndroidRuntime( 5656): at androidx.fragment.app.Fragment.instantiate(Fragment.java:678)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:507)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:81)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:2505)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:2665)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:117)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentActivity.lambda$init$3$androidx-fragment-app-FragmentActivity(FragmentActivity.java:140)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentActivity$$ExternalSyntheticLambda0.onContextAvailable(Unknown Source:2)
E/AndroidRuntime( 5656): at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
E/AndroidRuntime( 5656): at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:362)
E/AndroidRuntime( 5656): at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:217)
E/AndroidRuntime( 5656): at io.flutter.embedding.android.FlutterFragmentActivity.onCreate(FlutterFragmentActivity.java:279)
E/AndroidRuntime( 5656): ... 17 more
E/AndroidRuntime( 5656): Caused by: java.lang.NoSuchMethodException: com.reactnativestripesdk.GooglePayFragment.<init> []
E/AndroidRuntime( 5656): at java.lang.Class.getConstructor0(Class.java:2363)
E/AndroidRuntime( 5656): at java.lang.Class.getConstructor(Class.java:1759)
E/AndroidRuntime( 5656): at androidx.fragment.app.Fragment.instantiate(Fragment.java:663)
E/AndroidRuntime( 5656): ... 30 more
A current workaround for us is to remove the two fragments manually:
We remove PaymensSheetFragment
immediately after calling Stripe.instance.initPaymentSheet(...)
via a MethodChannel which calls this removePaymentSheetFragment(activity)
:
fun removePaymentSheetFragment(activity: FlutterFragmentActivity) = removeFragmentWithTag(activity, com.reactnativestripesdk.PaymentSheetFragment.TAG)
fun removeFragmentWithTag(activity: FlutterFragmentActivity, fragmentTag: String): Boolean{
return activity.supportFragmentManager.findFragmentByTag(fragmentTag)?.let{ possibleStripeFragment ->
activity.supportFragmentManager.beginTransaction()
.remove(possibleStripeFragment)
.commitAllowingStateLoss()
Log.d(TAG, "successfully removed ${possibleStripeFragment::class.simpleName}")
true
} ?: run {
Log.d(TAG, "didn't find a fragment to remove: $fragmentTag")
false
}
}
And we do the same with GooglePayFragment, except we remove than in our MainActivity.onResume()
.
This doesn't feel safe however, as we don't know if there are any side-effects to this, but it seems to fix the crashes without affecting our own payment flow in particular.
Also, I don't know if there are other fragments besides these two in the library, that also don't have a no-arg constructor which could cause crashes too.
I imagine that following the answer here could fix this crash in the library, by creating a newInstance(...)
function instead of using args in the Fragment-constructor.
Hello @remonh87, Any update on this ?
@thni-monta thank you for the great explanation. I did some studying and having a non 0 arg constructor looks indeed wrong. I have addressed the issue with Stripe since they should fix it in their sdk first, however at first hand it doesn't look easy to fix.
Any news on this @remonh87
I have the same problem. Occurs on android 10+, on some of the devices. Not on all of them.
Caused by androidx.fragment.app.Fragment$k: Unable to instantiate fragment g.n.t0: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(:94)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java)
at androidx.fragment.app.FragmentManager$2.instantiate(FragmentManager.java:17)
at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:2)
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:13)
at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:119)
at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:140)
at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:4)
at androidx.fragment.app.FragmentActivity.lambda$init$1(FragmentActivity.java:3)
at androidx.fragment.app.FragmentActivity.lambda$init$1$FragmentActivity(FragmentActivity.java)
at androidx.fragment.app.-$$Lambda$FragmentActivity$QtiQ2ZI3e38UkO1_xuJ8vE_JZj4.onContextAvailable(lambda:2)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:20)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:7)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java)
at io.flutter.embedding.android.FlutterFragmentActivity.onCreate(FlutterFragmentActivity.java:9)
at android.app.Activity.performCreate(Activity.java:8238)
at android.app.Activity.performCreate(Activity.java:8206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3710)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3904)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
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:2259)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:210)
at android.os.Looper.loop(Looper.java:299)
at android.app.ActivityThread.main(ActivityThread.java:8103)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)
I am not an android export, but couldn't the fragment be named better than g.n.t0? Or Is it some random name? How can i guess which fragment causes this crash and find the culprit plugin without the meanigful name? I use also in_app_purchases (do they use fragments?), but if i would have to guess, i would say that flutter_stripe is the culript. Do you have any news on that?
EDIT. Confirmed in debug mode that this is actually caused by flutter_stripe plugin. It crashes even though i never opened payment sheet at the first place.
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.reactnativestripesdk.PaymentLauncherFragment
Honestly, for me this plugin is not production ready with such a huge bug.
@incloudss we are dependent on the Stripe team to fix this issue (see https://github.com/stripe/stripe-react-native/issues/1262 ) . As long as this is open there is nothing we can do.