Skip to content

Commit 89d0c6c

Browse files
Create ActivitySourceRetrievalListener (#867)
Correctly handle Activity weak references in `AddSourceActivity`
1 parent 039f214 commit 89d0c6c

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

stripe/src/main/java/com/stripe/android/CustomerSession.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.stripe.android;
22

3+
import android.app.Activity;
34
import android.content.Context;
45
import android.content.Intent;
56
import android.os.Bundle;
@@ -17,6 +18,7 @@
1718
import com.stripe.android.model.ShippingInformation;
1819
import com.stripe.android.model.Source;
1920

21+
import java.lang.ref.WeakReference;
2022
import java.util.ArrayList;
2123
import java.util.Arrays;
2224
import java.util.Calendar;
@@ -776,6 +778,24 @@ void onError(int errorCode, @Nullable String errorMessage,
776778
@Nullable StripeError stripeError);
777779
}
778780

781+
/**
782+
* Abstract implementation of {@link SourceRetrievalListener} that holds a
783+
* {@link WeakReference} to an {@link Activity} object.
784+
*/
785+
public abstract static class ActivitySourceRetrievalListener<A extends Activity>
786+
implements SourceRetrievalListener {
787+
@NonNull private final WeakReference<A> mActivityRef;
788+
789+
public ActivitySourceRetrievalListener(@NonNull A activity) {
790+
this.mActivityRef = new WeakReference<>(activity);
791+
}
792+
793+
@Nullable
794+
protected A getActivity() {
795+
return mActivityRef.get();
796+
}
797+
}
798+
779799
private static class CustomerMessage {
780800
@Nullable private final String operationId;
781801
@Nullable private final Customer customer;

stripe/src/main/java/com/stripe/android/view/AddSourceActivity.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import android.view.KeyEvent;
1111
import android.view.inputmethod.EditorInfo;
1212
import android.view.inputmethod.InputMethodManager;
13-
import android.widget.FrameLayout;
1413
import android.widget.TextView;
1514

1615
import com.stripe.android.ActivitySourceCallback;
@@ -42,7 +41,6 @@ public class AddSourceActivity extends StripeActivity {
4241

4342
@Nullable private CardMultilineWidget mCardMultilineWidget;
4443
@Nullable private CustomerSessionProxy mCustomerSessionProxy;
45-
private FrameLayout mErrorLayout;
4644
@Nullable private StripeProvider mStripeProvider;
4745

4846
private boolean mStartedFromPaymentSession;
@@ -90,8 +88,7 @@ protected void onCreate(Bundle savedInstanceState) {
9088
mViewStub.inflate();
9189
mCardMultilineWidget = findViewById(R.id.add_source_card_entry_widget);
9290
initEnterListeners();
93-
mErrorLayout = findViewById(R.id.add_source_error_container);
94-
boolean showZip = getIntent().getBooleanExtra(EXTRA_SHOW_ZIP, false);
91+
final boolean showZip = getIntent().getBooleanExtra(EXTRA_SHOW_ZIP, false);
9592
mUpdatesCustomer = getIntent().getBooleanExtra(EXTRA_UPDATE_CUSTOMER, false);
9693
mStartedFromPaymentSession =
9794
getIntent().getBooleanExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true);
@@ -123,7 +120,7 @@ void initCustomerSessionTokens() {
123120

124121
@Override
125122
protected void onActionSave() {
126-
final Card card = mCardMultilineWidget.getCard();
123+
final Card card = mCardMultilineWidget != null ? mCardMultilineWidget.getCard() : null;
127124
if (card == null) {
128125
// In this case, the error will be displayed on the card widget itself.
129126
return;
@@ -142,20 +139,7 @@ protected void onActionSave() {
142139

143140
private void attachCardToCustomer(@NonNull final StripePaymentSource source) {
144141
final CustomerSession.SourceRetrievalListener listener =
145-
new CustomerSession.SourceRetrievalListener() {
146-
@Override
147-
public void onSourceRetrieved(@NonNull Source source) {
148-
finishWithSource(source);
149-
}
150-
151-
@Override
152-
public void onError(int errorCode, @Nullable String errorMessage,
153-
@Nullable StripeError stripeError) {
154-
// No need to show this error, because it will be broadcast
155-
// from the CustomerSession
156-
setCommunicatingProgress(false);
157-
}
158-
};
142+
new SourceRetrievalListenerImpl(this);
159143

160144
if (mCustomerSessionProxy == null) {
161145
@Source.SourceType final String sourceType;
@@ -277,4 +261,34 @@ public void onSuccess(@NonNull Source source) {
277261
}
278262
}
279263
}
264+
265+
private static final class SourceRetrievalListenerImpl
266+
extends CustomerSession.ActivitySourceRetrievalListener<AddSourceActivity> {
267+
private SourceRetrievalListenerImpl(@NonNull AddSourceActivity activity) {
268+
super(activity);
269+
}
270+
271+
@Override
272+
public void onSourceRetrieved(@NonNull Source source) {
273+
final AddSourceActivity activity = getActivity();
274+
if (activity == null) {
275+
return;
276+
}
277+
278+
activity.finishWithSource(source);
279+
}
280+
281+
@Override
282+
public void onError(int errorCode, @Nullable String errorMessage,
283+
@Nullable StripeError stripeError) {
284+
final AddSourceActivity activity = getActivity();
285+
if (activity == null) {
286+
return;
287+
}
288+
289+
// No need to show this error, because it will be broadcast
290+
// from the CustomerSession
291+
activity.setCommunicatingProgress(false);
292+
}
293+
}
280294
}

0 commit comments

Comments
 (0)