【问题标题】:In App Billing BroadcastReceiver Memory LeakIn App Billing BroadcastReceiver 内存泄漏
【发布时间】:2019-08-06 09:20:29
【问题描述】:

我正在使用 ActivityResult 打开一个活动,在成功购买商品后,我正在关闭当前的活动,该活动持有购买过程并发回数据。但是 Leak Canary 发现了有关 BillingBroadcastReceiver 的内存泄漏。我初始化计费客户端OnCreate 并释放onDestroy

这是我在OnCreate中调用的init方法

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");
            }
        });

billingClient 准备好时加载产品信息

private void loadProducts() {

if (billingClient.isReady()) {

    List<String> skuList = new ArrayList<>(getViewModel().getSkuIdList());
    SkuDetailsParams params = SkuDetailsParams.newBuilder().setSkusList(skuList).setType(BillingClient.SkuType.INAPP).build();

    billingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(int responseCode, List<SkuDetails> skuDetailsList) {

            if (responseCode == BillingClient.BillingResponse.OK) {
                Timber.d("SkuList --> %s", skuDetailsList.size());

            } else {
                Timber.d("Can't querySkuDetailsAsync, responseCode: %s", responseCode);
            }

        }
    });

} else {
    Timber.d("Billing Client not Ready");
}
}

这是我在OnDestroy中调用的发布方法

    if (billingClient != null && billingClient.isReady()) {
        billingClient.endConnection();
        billingClient = null;
    }

OnPurchaseUpdated 我进行了服务调用并根据服务结果关闭此活动。

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");
    }
}

我正在使用最新的库进行应用内购买

implementation 'com.android.billingclient:billing:1.2.1'

成功购买物品并关闭最近的活动后,Leak Canary 向我显示此错误。如何避免这种内存泄漏?

【问题讨论】:

  • 看起来endConnection 没有删除对setListener(this) 正在设置的活动的引用。您是否通过设置断点验证了 billingClient.endConnection(); 确实被调用了?
  • 我通过设置断点检查,billingClient.endConnection(); 正常调用。我还在informPurchase 方法的观察者中调用endConnection 方法进行测试,仍然发生同样的泄漏@CésarDeLaVega
  • 同时添加你的广播管理器类
  • 问题出在@ShwetaChauhan,我没有boardcastmanager 类,它是计费库的类
  • @dtunctuncer 不幸的是:(

标签: android memory-leaks in-app-billing


【解决方案1】:

Activity 在billingClient 准备好之前就被销毁了,所以 billingClient.isReady 将为 false,并且永远不会调用 endConnection,因此不会删除对 Activity 的引用(Activity 是 BillingClient 的侦听器),并且您将有泄漏。

要修复,只需:

if (billingClient != null) {
        billingClient.endConnection();
        billingClient = null;
}

【讨论】:

  • 感谢您的回答,但没有奏效。 billingClient 始终准备就绪,billingClient.endConnection(); 调用正确,我通过调试进行了仔细检查。我还检查了删除isReady,结果还是一样
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2010-09-16
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2010-12-01
  • 2014-11-12
  • 1970-01-01
相关资源
最近更新 更多