stripe-android icon indicating copy to clipboard operation
stripe-android copied to clipboard

TextView$SavedState cannot be cast to com.stripe.android.view.StripeEditText$StripeEditTextState

Open Atternatt opened this issue 1 year ago • 3 comments

Summary

We are facing an issue since many versions ago. We have been delaying this issue as it has not been much impactful until now. We are having some spikes and we would like to come with a fix asap :)

Code to reproduce

We can't reproduce and the feedback compres from several different devices and version here is the log of one crash:

          Fatal Exception: java.lang.ClassCastException: android.widget.TextView$SavedState cannot be cast to com.stripe.android.view.StripeEditText$StripeEditTextState
       at com.stripe.android.view.StripeEditText.onRestoreInstanceState(StripeEditText.kt:255)
       at com.stripe.android.view.CardNumberEditText.onRestoreInstanceState(CardNumberEditText.kt:323)
       at android.view.View.dispatchRestoreInstanceState(View.java:22756)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at com.google.android.material.textfield.TextInputLayout.dispatchRestoreInstanceState(TextInputLayout.java:3171)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4219)
       at android.view.View.restoreHierarchyState(View.java:22734)
       at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:699)
       at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:3177)
       at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3162)
       at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:631)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
       at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1614)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3198)
       at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3116)
       at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3163)
       at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:631)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
       at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1614)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3198)
       at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3116)
       at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:263)
       at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:350)
       at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1510)
       at android.app.Activity.performStart(Activity.java:8616)
       at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4204)
       at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
       at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
       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:8762)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
        

Android version

Screenshot 2024-07-08 at 12 40 35

Impacted devices

Screenshot 2024-07-08 at 12 40 16

Installation method

Gradle

Dependency Versions

kotlin: 2.0.0 stripe-android: 20.47.0 Android Gradle Plugin: 8.4.0 Gradle: gradle-8.7

SDK classes

N/A

Video

Other information

Screenshot 2024-07-08 at 12 44 30

Atternatt avatar Jul 08 '24 10:07 Atternatt

Ping, is there anyone who could provide feedback?

Atternatt avatar Sep 02 '24 13:09 Atternatt

Hey @Atternatt, can you provide more information on your integration or steps to reproduce?

tjclawson-stripe avatar Oct 07 '24 16:10 tjclawson-stripe

hello @tjclawson-stripe the issue is the this is the only information we can provide. We, devs, are unable to reproduce but the issue is appearing quite a lot of times. My feeling is that this is happening in a Android configuration change.

Atternatt avatar Oct 08 '24 10:10 Atternatt

We've made a few fixes in the most recent release. Please upgrade and let us know if you can still reproduce this.

jaynewstrom-stripe avatar Nov 08 '24 19:11 jaynewstrom-stripe

@jaynewstrom-stripe I was able to finally reproduce the issue. It's happening when changing from dark/light mode because the state arriving in the onRestoreInstanceState is TextView.SavedState.

https://github.com/stripe/stripe-android/blob/c0e0e752594523cba27d42a1f954a5e376406fc9/payments-core/src/main/java/com/stripe/android/view/StripeEditText.kt#L255

Screenshot 2024-12-03 at 16 08 57

Any chance you could do a nullable cast here since you already have a let? I can open a PR with that, if needed.

prof18 avatar Dec 03 '24 15:12 prof18

If you want to open a PR, and validate the fix, that would be fantastic!

jaynewstrom-stripe avatar Dec 03 '24 15:12 jaynewstrom-stripe

Cool, will do!

prof18 avatar Dec 03 '24 15:12 prof18