我要打开一个带有ActivityResult的Activity,并在成功购买商品后关闭当前的活动,该活动保存着采购过程并将数据发送回去。但是Leak Canary遇到了关于BillingBroadcastReceiver的内存泄漏。我初始化了计费客户端Index startIndex = 1;
Index endIndex = 3;
var NewList=CountryList[startIndex..endIndex]
,然后释放OnCreate
。
这是我在onDestroy
中调用的init方法
OnCreate
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
OnPurchaseUpdated我打了一个服务电话,并根据服务结果关闭此活动。
if (billingClient != null && billingClient.isReady()) {
billingClient.endConnection();
billingClient = null;
}
我正在使用最新的库进行应用内购买
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");
}
}
成功购买商品并关闭近期活动后,Leak Canary向我显示此错误。如何避免这种内存泄漏?
答案 0 :(得分:1)
在if
if (ValidateUser(Login1.UserName, Login1.Password))
{
e.Authenticated = true;
}
else
{
e.Authenticated = false;
}
准备就绪之前,活动已被销毁,因此
billingClient
将为false,并且将永远不会调用billingClient.isReady
,因此不会删除对Activity的引用(Activity是BillingClient的侦听器),并且会泄漏。 >
要解决,只需执行以下操作:
endConnection