play-billing-samples: BillingBroadcastReceiver Memory Leak
After buying a item successfully, I am closing the current activity which holds purching process. But Leak Canary catch a memory leak about BillingBroadcastReceiver
. I init billing client OnCreate
and release onDestroy
.
Here is my init method
billingClient = BillingClient.newBuilder(this).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(int responseCode) {
if (responseCode == BillingClient.BillingResponse.OK) {
// The billing client is ready. You can query purchases here.
loadProducts();
} else {
// Error
}
}
@Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
Timber.d("Connection Error");
}
});
Here is my release Method
if (billingClient != null && billingClient.isReady()) {
billingClient.endConnection();
billingClient = null;
}
OnPurchaseUpdated I made a service call and close this activity based on service result.
public void onPurchasesUpdated(int responseCode, @Nullable List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK && purchases != null) {
for (Purchase purchase : purchases) {
billingClient.consumeAsync(purchase.getPurchaseToken(), new ConsumeResponseListener() {
@Override
public void onConsumeResponse(int responseCode, String purchaseToken) {
if (responseCode == BillingClient.BillingResponse.OK && purchaseToken != null) {
Timber.d("onConsumeResponse --> %s", purchaseToken);
getViewModel().informPurchase(necessary data);
}
}
});
}
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
// Handle an error caused by a user canceling the purchase flow.
Timber.d("Billing Cancelled");
} else {
Timber.d("An Error Occured");
}
}
Here is the Leak Canary error
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 1
- Comments: 24 (1 by maintainers)
With billingClient 4.1.0 still have a similar leak. Looks like
billingClient.endConnection()
doesn’t destroy some Handler with a reference to some listenerI believe we found the issue: PBL is holding an activity context and didn’t free it. The issue has been fixed. It shall be rolled out with the next PBL release.
On Thu, Jan 7, 2021 at 2:29 AM haris15 notifications@github.com wrote:
Same problem with me too. Can reproduce it by toggling between dark mode and light mode.
Might you be able to follow the TrivialDriveKotlin sample so as to decouple your billing implementation from your activity lifecycle?
You don’t need to check isReady() before calling endConnection(). Otherwise, the serviceConnection could still live (even if it is not ready) without being ended.