Skip to content

Commit

Permalink
Fix memory leaks in example app
Browse files Browse the repository at this point in the history
**Summary**
- Create `ActivitySourceCallback` to help with memory
  handling
- Refactor and clean-up classes in example app to fix
  memory leaks as identified by LeakCanary
- Call `CompositeSubscription#unsubscribe()` in
  `Activity#onDestroy()` where missing

**Motivation**
ANDROID-349

**Testing**
Ran example app
  • Loading branch information
mshafrir-stripe committed Apr 11, 2019
1 parent 7208c62 commit c9150d4
Show file tree
Hide file tree
Showing 19 changed files with 235 additions and 143 deletions.
Expand Up @@ -50,7 +50,7 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onStringResponse(String string) {
if (string.startsWith("Error: ")) {
mErrorDialogHandler.showError(string);
mErrorDialogHandler.show(string);
}
}
}));
Expand All @@ -68,7 +68,7 @@ public void onCustomerRetrieved(@NonNull Customer customer) {
public void onError(int httpCode, @Nullable String errorMessage,
@Nullable StripeError stripeError) {
mSelectSourceButton.setEnabled(false);
mErrorDialogHandler.showError(errorMessage);
mErrorDialogHandler.show(errorMessage);
mProgressBar.setVisibility(View.INVISIBLE);
}
});
Expand Down
Expand Up @@ -45,9 +45,11 @@ public class PaymentIntentActivity extends AppCompatActivity {
private static final String TAG = PaymentIntentActivity.class.getName();

private static final String RETURN_URL = "stripe://payment_intent_return";

@NonNull private final CompositeSubscription mCompositeSubscription =
new CompositeSubscription();
private ProgressDialogController mProgressDialogController;
private ErrorDialogHandler mErrorDialogHandler;
private CompositeSubscription mCompositeSubscription;
private Stripe mStripe;
private StripeService mStripeService;
private String mClientSecret;
Expand All @@ -60,16 +62,15 @@ public class PaymentIntentActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_intent_demo);
Button createPaymentIntent = findViewById(R.id.btn_create_payment_intent);
final Button createPaymentIntent = findViewById(R.id.btn_create_payment_intent);
mRetrievePaymentIntent = findViewById(R.id.btn_retrieve_payment_intent);
mConfirmPaymentIntent = findViewById(R.id.btn_confirm_payment_intent);
mPaymentIntentValue = findViewById(R.id.payment_intent_value);
mCardInputWidget = findViewById(R.id.card_input_widget);
mProgressDialogController =
new ProgressDialogController(getSupportFragmentManager());

mProgressDialogController = new ProgressDialogController(getSupportFragmentManager(),
getResources());
mErrorDialogHandler = new ErrorDialogHandler(getSupportFragmentManager());
mCompositeSubscription = new CompositeSubscription();
mStripe = new Stripe(getApplicationContext());
Retrofit retrofit = RetrofitFactory.getInstance();
mStripeService = retrofit.create(StripeService.class);
Expand Down Expand Up @@ -98,6 +99,13 @@ public void onClick(View v) {
});
}

@Override
protected void onDestroy() {
mCompositeSubscription.unsubscribe();
super.onDestroy();
}

@NonNull
private Map<String, Object> createPaymentIntentParams() {
final Map<String, Object> params = new HashMap<>();
params.put("allowed_source_types[]", "card");
Expand All @@ -113,14 +121,13 @@ void createPaymentIntent() {
.doOnSubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.setMessageResource(R.string.creating_payment_intent);
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.creating_payment_intent);
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}
})
.subscribe(
Expand All @@ -143,7 +150,7 @@ public void call(ResponseBody responseBody) {
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mErrorDialogHandler.showError(throwable.getLocalizedMessage());
mErrorDialogHandler.show(throwable.getLocalizedMessage());
}
}
);
Expand All @@ -165,14 +172,13 @@ public PaymentIntent call() throws Exception {
.doOnSubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.setMessageResource(R.string.retrieving_payment_intent);
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.retrieving_payment_intent);
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}
})
.observeOn(AndroidSchedulers.mainThread()).subscribe(
Expand Down Expand Up @@ -216,14 +222,13 @@ public PaymentIntent call() throws Exception {
.doOnSubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.setMessageResource(R.string.confirming_payment_intent);
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.confirming_payment_intent);
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}
})
.subscribe(
Expand Down
@@ -1,6 +1,7 @@
package com.stripe.example.activity;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
Expand Down Expand Up @@ -37,7 +38,9 @@ public class PaymentMultilineActivity extends AppCompatActivity {
ErrorDialogHandler mErrorDialogHandler;

CardMultilineWidget mCardMultilineWidget;
CompositeSubscription mCompositeSubscription;

@NonNull private final CompositeSubscription mCompositeSubscription =
new CompositeSubscription();

private SimpleAdapter mSimpleAdapter;
private List<Map<String, String>> mCardSources= new ArrayList<>();
Expand All @@ -47,11 +50,10 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_multiline);

mCompositeSubscription = new CompositeSubscription();
mCardMultilineWidget = findViewById(R.id.card_multiline_widget);

mProgressDialogController =
new ProgressDialogController(getSupportFragmentManager());
mProgressDialogController = new ProgressDialogController(getSupportFragmentManager(),
getResources());

mErrorDialogHandler = new ErrorDialogHandler(getSupportFragmentManager());

Expand Down Expand Up @@ -100,14 +102,14 @@ public Source call() throws Exception {
new Action0() {
@Override
public void call() {
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.progressMessage);
}
})
.doOnUnsubscribe(
new Action0() {
@Override
public void call() {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}
})
.subscribe(
Expand All @@ -120,7 +122,7 @@ public void call(Source source) {
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mErrorDialogHandler.showError(throwable.getLocalizedMessage());
mErrorDialogHandler.show(throwable.getLocalizedMessage());
}
}));
}
Expand All @@ -139,4 +141,9 @@ private void addToList(@Nullable Source source) {
mSimpleAdapter.notifyDataSetChanged();
}

@Override
protected void onDestroy() {
mCompositeSubscription.unsubscribe();
super.onDestroy();
}
}
Expand Up @@ -123,7 +123,7 @@ private void setupCustomerSession() {
@Override
public void onStringResponse(String string) {
if (string.startsWith("Error: ")) {
mErrorDialogHandler.showError(string);
mErrorDialogHandler.show(string);
}
}
}));
Expand All @@ -142,7 +142,7 @@ public void onError(int httpCode, @Nullable String errorMessage,
mCustomer = null;
mSelectPaymentButton.setEnabled(false);
mSelectShippingButton.setEnabled(false);
mErrorDialogHandler.showError(errorMessage);
mErrorDialogHandler.show(errorMessage);
mProgressBar.setVisibility(View.INVISIBLE);
}
});
Expand Down Expand Up @@ -287,7 +287,7 @@ public void onError(int errorCode, @Nullable String errorMessage) {
return;
}

activity.mErrorDialogHandler.showError(errorMessage);
activity.mErrorDialogHandler.show(errorMessage);
}

@Override
Expand Down
Expand Up @@ -44,8 +44,10 @@ public class RedirectActivity extends AppCompatActivity {
private static final String QUERY_CLIENT_SECRET = "client_secret";
private static final String QUERY_SOURCE_ID = "source";

@NonNull private final CompositeSubscription mCompositeSubscription =
new CompositeSubscription();

private CardInputWidget mCardInputWidget;
private CompositeSubscription mCompositeSubscription;
private RedirectAdapter mRedirectAdapter;
private ErrorDialogHandler mErrorDialogHandler;
private RedirectDialogController mRedirectDialogController;
Expand All @@ -58,10 +60,10 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_polling);

mCompositeSubscription = new CompositeSubscription();
mCardInputWidget = findViewById(R.id.card_widget_three_d);
mErrorDialogHandler = new ErrorDialogHandler(this.getSupportFragmentManager());
mProgressDialogController = new ProgressDialogController(this.getSupportFragmentManager());
mProgressDialogController = new ProgressDialogController(this.getSupportFragmentManager(),
getResources());
mRedirectDialogController = new RedirectDialogController(this);
mStripe = new Stripe(getApplicationContext());

Expand Down Expand Up @@ -113,8 +115,8 @@ protected void onNewIntent(Intent intent) {

@Override
protected void onDestroy() {
super.onDestroy();
mCompositeSubscription.unsubscribe();
super.onDestroy();
}

void beginSequence() {
Expand Down Expand Up @@ -149,8 +151,7 @@ public Source call() throws Exception {
.doOnSubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.setMessageResource(R.string.createSource);
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.createSource);
}
})
.subscribe(
Expand All @@ -176,15 +177,15 @@ public void call(Source source) {
// The card Source can be used to create a 3DS Source
createThreeDSecureSource(source.getId());
} else {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}

}
},
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mErrorDialogHandler.showError(throwable.getMessage());
mErrorDialogHandler.show(throwable.getMessage());
}
}
));
Expand Down Expand Up @@ -221,7 +222,7 @@ public Source call() throws Exception {
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
mProgressDialogController.finishProgress();
mProgressDialogController.dismiss();
}
})
.subscribe(
Expand All @@ -238,7 +239,7 @@ public void call(Source source) {
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mErrorDialogHandler.showError(throwable.getMessage());
mErrorDialogHandler.show(throwable.getMessage());
}
}
));
Expand Down
Expand Up @@ -12,6 +12,7 @@
import com.stripe.android.model.Card;
import com.stripe.android.model.Token;
import com.stripe.android.view.CardInputWidget;
import com.stripe.example.R;

/**
* Logic needed to create tokens using the {@link android.os.AsyncTask} methods included in the
Expand All @@ -21,7 +22,6 @@ public class AsyncTaskTokenController {

@NonNull private final Stripe mStripe;
@NonNull private final ErrorDialogHandler mErrorDialogHandler;
@NonNull private final ListViewController mOutputListController;
@NonNull private final ProgressDialogController mProgressDialogController;

@Nullable private CardInputWidget mCardInputWidget;
Expand All @@ -30,19 +30,22 @@ public AsyncTaskTokenController(
@NonNull Button button,
@NonNull CardInputWidget cardInputWidget,
@NonNull Context context,
@NonNull ErrorDialogHandler errorDialogHandler,
@NonNull ListViewController outputListController,
@NonNull ProgressDialogController progressDialogController) {
@NonNull final ErrorDialogHandler errorDialogHandler,
@NonNull final ListViewController outputListController,
@NonNull final ProgressDialogController progressDialogController) {
mCardInputWidget = cardInputWidget;
mStripe = new Stripe(context);
mErrorDialogHandler = errorDialogHandler;
mProgressDialogController = progressDialogController;
mOutputListController = outputListController;

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveCard();
saveCard(new TokenCallbackImpl(
errorDialogHandler,
outputListController,
progressDialogController
));
}
});
}
Expand All @@ -51,25 +54,39 @@ public void detach() {
mCardInputWidget = null;
}

private void saveCard() {
final Card cardToSave = mCardInputWidget.getCard();
private void saveCard(@NonNull TokenCallback tokenCallback) {
final Card cardToSave = mCardInputWidget != null ? mCardInputWidget.getCard() : null;
if (cardToSave == null) {
mErrorDialogHandler.showError("Invalid Card Data");
mErrorDialogHandler.show("Invalid Card Data");
return;
}
mProgressDialogController.startProgress();
mProgressDialogController.show(R.string.progressMessage);
mStripe.createToken(
cardToSave,
PaymentConfiguration.getInstance().getPublishableKey(),
new TokenCallback() {
public void onSuccess(@NonNull Token token) {
mOutputListController.addToList(token);
mProgressDialogController.finishProgress();
}
public void onError(@NonNull Exception error) {
mErrorDialogHandler.showError(error.getLocalizedMessage());
mProgressDialogController.finishProgress();
}
});
tokenCallback);
}

private static class TokenCallbackImpl implements TokenCallback {
@NonNull private final ErrorDialogHandler mErrorDialogHandler;
@NonNull private final ListViewController mOutputListController;
@NonNull private final ProgressDialogController mProgressDialogController;

private TokenCallbackImpl(@NonNull ErrorDialogHandler errorDialogHandler,
@NonNull ListViewController outputListController,
@NonNull ProgressDialogController progressDialogController) {
this.mErrorDialogHandler = errorDialogHandler;
this.mOutputListController = outputListController;
this.mProgressDialogController = progressDialogController;
}

public void onSuccess(@NonNull Token token) {
mOutputListController.addToList(token);
mProgressDialogController.dismiss();
}
public void onError(@NonNull Exception error) {
mErrorDialogHandler.show(error.getLocalizedMessage());
mProgressDialogController.dismiss();
}
}
}

0 comments on commit c9150d4

Please sign in to comment.