【发布时间】: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