stripe-android
stripe-android copied to clipboard
com.stripe.android.view.CardInputWidget crashes when inflated inside BottomSheetDialog
Summary
Hi, I'm having a problem with
com.stripe.android.view.CardInputWidget
- it crashes when inflated inside BottomSheetDialog from SDK version 20.32.0
- version 20.31.0
is fine. The issue is still present in the latest SDK version 20.36.0
. Compiles fine and crash happens at runtime on Android 14 (haven't tested other Android versions).
I've tested using the CardInputWidget
inside the Fragment that launches the BottomSheetDialog and that seems to work fine - so it does seem like this has something particular to do with BottomSheetDialog.
Code to reproduce
View creation happens via inflation inside an xml file:
<com.stripe.android.view.CardInputWidget
android:id="@+id/cardInputWidget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
Which is then inflated inside a com.google.android.material.bottomsheet.BottomSheetDialog
using a view binding:
val viewBinding = CardInputBinding.inflate(layoutInflater)
Android version
Android 14
Impacted devices
Haven't tested other devices - happens on Pixel 7.
Installation method
Via gradle dependency.
Dependency Versions
kotlin: 1.9.10 stripe-android: 20.32.0 Android Gradle Plugin: 8.1.4 Gradle: 8.0
SDK classes
com.stripe.android.view.CardInputWidget
Video
Other information
This issue looks similar to the one described in https://github.com/stripe/stripe-android/issues/7484 and started occurring in the same release. It has not been fixed in the latest version (20.36.0) of the SDK though.
Stack Trace only contains Android SDK classes:
AndroidRuntime E FATAL EXCEPTION: main
E Process: com.depop.dev, PID: 7068
E java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from android.widget.FrameLayout{3565a3d V.E...... ......I. 0,0-0,0 #7f0a02ff app:id/container}
E at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:352)
E at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:325)
E at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$LifecycleAware$1.createRecomposer(WindowRecomposer.android.kt:168)
E at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:224)
E at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:300)
E at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:244)
E at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:251)
E at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:283)
E at android.view.View.dispatchAttachedToWindow(View.java:21980)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
E at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3014)
E at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
E at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
E at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
E at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
E at android.view.Choreographer.doCallbacks(Choreographer.java:952)
E at android.view.Choreographer.doFrame(Choreographer.java:882)
E at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
E at android.os.Handler.handleCallback(Handler.java:958)
E at android.os.Handler.dispatchMessage(Handler.java:99)
E at android.os.Looper.loopOnce(Looper.java:205)
E at android.os.Looper.loop(Looper.java:294)
E at android.app.ActivityThread.main(ActivityThread.java:8177)
E at java.lang.reflect.Method.invoke(Native Method)
E at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Hi @grepx 👋 Thanks for reporting this issue, and for the detailed description. I’m able to reproduce the crash.
I’ll look into a solution for BottomSheetDialog
. In the meantime, is it feasible for you to switch to a BottomSheetDialogFragment
? This one is a Fragment
and thus a LifecycleOwner
, which means that the crash won’t occur.
Even easier: We provide a pre-built bottom sheet called PaymentSheet
, where you wouldn’t have to build any UI yourself. The docs are here and I’d be more than happy to help with the migration. It does support lots of local payment methods across the world, but you can also limit it to just cards if you want.
I'd also love to see this fixed, as it is blocking me from implementing the co-badged-card requirements on the CardInputWidget
, as I need to move from 20.29.2
to > 20.37.4
:
https://docs.stripe.com/co-badged-cards-compliance?type=mobile-elements&mobile-ui=card-element#integration-guides
On the older version, there is no crash, however on the newer version it crashes.
View dialogView = LayoutInflater.from(this).inflate(R.layout.pv_stripe_card_input_widget, null);
com.stripe.android.view.CardInputWidget cardInputWidget = dialogView.findViewById(R.id.cardInputWidget);
androidx.appcompat.app.AlertDialog cardInputDialog = new MaterialAlertDialogBuilder(this, R.style.PaymentAlertDialogStyle)
.setView(dialogView)
.create();
cardInputDialog.show();
I'm going to close this as a duplicate of https://github.com/stripe/stripe-android/issues/8625
I realize this isn't fixed yet, and I apologize for that. We will work on a path forward and update the other issue when we have something to share.