braintree / braintree-android-drop-in

Braintree Drop-In SDK for Android
https://developers.braintreepayments.com/guides/drop-in/android/v2
MIT License
124 stars 78 forks source link

Attempting to launch an unregistered ActivityResultLauncher #483

Closed mattaojie closed 1 month ago

mattaojie commented 1 month ago

Braintree SDK Version

6.16.0

Environment

Production

Android Version & Device

No response

Braintree dependencies

com.braintreepayments.api:drop-in:6.16.0

Describe the bug

java.lang.IllegalStateException: Attempting to launch an unregistered ActivityResultLauncher with contract com.braintreepayments.api.DropInActivityResultContract@a901791 and input com.braintreepayments.api.DropInIntentData@1ae66f6. You must ensure the ActivityResultLauncher is registered before calling launch(). at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:168) at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47) at com.braintreepayments.api.DropInLifecycleObserver.launch(DropInLifecycleObserver.java:38) at com.braintreepayments.api.DropInClient.lambda$launchDropIn$2$com-braintreepayments-api-DropInClient(DropInClient.java:278) at com.braintreepayments.api.DropInClient$$ExternalSyntheticLambda3.onAuthorizationResult(Unknown Source:4) at com.braintreepayments.api.AuthorizationLoader$loadAuthorization$1.onSuccess(AuthorizationLoader.kt:17)

To reproduce

I am using the Android Navigation component and have two fragments, each with its own DropInClient object. When navigating from fragment A to fragment B and calling dropInClient.launchDropIn(dropInRequest) in fragment B, the app crashes. I suspect the reason is that fragment A's onDestroyView method is called later than fragment B's onStart method, causing the ActivityResultRegistry to invoke the unregister method. Even though these are different instances of DropInClient, they share the same mActivityResultRegistry of the Activity. When I use the dropInClient.launchDropInForResult method in fragment B, everything works fine.

Expected behavior

Perhaps using different DROP_IN_RESULT values as the callback key for different instances of DropInLifecycleObserver in the ActivityResultRegistry might solve this issue?

Screenshots

No response

sshropshire commented 1 month ago

Hi @mattaojie thanks for using the Braintree SDK for Android.

This is a unique scenario. First can I ask is it possible to have a single DropInClient reference live in the host Activity? Alternatively is it possible to have a single DropInClient reference in either Fragment A or Fragment B?

mattaojie commented 1 month ago

Placing the DropInClient instance in the Activity does indeed solve the problem, but I might need to occasionally call invalidateClientToken since these two fragments have different functionalities. I might also need to store the token locally myself. Thank you for your response.

sshropshire commented 1 month ago

@mattaojie glad it worked out! I'll close this for now.

We're working to improve the developer experience of these scenarios. We recently released a beta version of our core SDK to remove restrictions on feature clients (e.g. DropInClient) and onCreate() instantiation. These changes will propagate up to our DropIn SDK in time.