question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BillingBroadcastReceiver Memory Leak

See original GitHub issue

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

BroadcastError

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:1
  • Comments:23 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
aloz77commented, Mar 22, 2022

With billingClient 4.1.0 still have a similar leak. Looks like billingClient.endConnection() doesn’t destroy some Handler with a reference to some listener

    ┬───
    β”‚ GC Root: System class
    β”‚
    β”œβ”€ android.app.ActivityThread class
    β”‚    Leaking: NO (MessageQueue↓ is not leaking and a class is never leaking)
    β”‚    ↓ static ActivityThread.sMainThreadHandler
    β”œβ”€ android.app.ActivityThread$H instance
    β”‚    Leaking: NO (MessageQueue↓ is not leaking)
    β”‚    ↓ Handler.mQueue
    β”œβ”€ android.os.MessageQueue instance
    β”‚    Leaking: NO (MessageQueue#mQuitting is false)
    β”‚    HandlerThread: "main"
    β”‚    ↓ MessageQueue[2]
    β”‚                  ~~~
    β”œβ”€ android.os.Message instance
    β”‚    Leaking: UNKNOWN
    β”‚    Retaining 120 B in 4 objects
    β”‚    Message.what = 0
    β”‚    Message.when = 23510943 (16342 ms after heap dump)
    β”‚    Message.obj = null
    β”‚    Message.callback = instance @317222688 of com.android.billingclient.api.zzz
    β”‚    Message.target = instance @317222768 of android.os.Handler
    β”‚    ↓ Message.callback
    β”‚              ~~~~~~~~
    β”œβ”€ com.android.billingclient.api.zzz instance
    β”‚    Leaking: UNKNOWN
    β”‚    Retaining 56 B in 3 objects
    β”‚    ↓ zzz.zzb
    β”‚          ~~~
    β”œβ”€ com.android.billingclient.api.zzy instance
    β”‚    Leaking: UNKNOWN
    β”‚    Retaining 12 B in 1 objects
    β”‚    ↓ zzy.zza
    β”‚          ~~~
    β”œβ”€ com.my.app.OrderFragment$1 instance
    β”‚    Leaking: UNKNOWN
    β”‚    Retaining 12 B in 1 objects
    β”‚    Anonymous class implementing com.android.billingclient.api.SkuDetailsResponseListener
    β”‚    ↓ OrderFragment$1.this$0
    β”‚                      ~~~~~~
    β•°β†’ com.my.app.OrderFragment instance
    ​     Leaking: YES (ObjectWatcher was watching this because com.my.app.OrderFragment received Fragment#onDestroy()
    ​     callback and Fragment#mFragmentManager is null)
    ​     Retaining 2,5 MB in 14148 objects
    ​     key = f04ce3ba-e9b2-470d-bfca-ad05e6f57e98
    ​     watchDurationMillis = 7928
    ​     retainedDurationMillis = 2928
    ​     mainActivity instance of com.my.app.MainActivity with mDestroyed = true
    ====================================
    0 LIBRARY LEAKS
5reactions
Qing451800commented, Jan 7, 2021

I 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:

@yusufceylan https://github.com/yusufceylan have you found any solution ? if yes then help me

β€” You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/android/play-billing-samples/issues/185#issuecomment-756030039, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOOVKZHP373H36O6C7ZAC2LSYWEJ7ANCNFSM4G6YKTAQ .

Read more comments on GitHub >

github_iconTop Results From Across the Web

In App Billing BroadcastReceiver Memory Leak - Stack Overflow
I am opening a Activity with ActivityResult and after buying a item successfully, I am closing the current activity which holds purching processΒ ......
Read more >
In App Billing Broadcastreceiver Memory Leak - ADocLib
secure applications that do not leak or alter user data in the presence of an adversary. another Activity that prompts the user for...
Read more >
Gist to demonstrate memory leak when using Broadcast ...
* You need to unregister the broadcast receiver since the broadcast receiver keeps a reference of the activity. * is still holding a...
Read more >
Broadcasts overview | Android Developers
Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern.
Read more >
Memory Leaks in details in Android | by SHISHIR - Medium
A memory leak happens when memory is allocated but never freed. This means the garbage collector is not able to take out the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found