几乎所有使用远程服务的例子都包含这样的代码(这个代码来自Google IabHelper)
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
logDebug("Billing service connected.");
mService = getServiceFromBinder(service);
...
}
};
为什么字段mService始终设置为null?忽略onServiceConnected回调是不对的?根据我的经验,重新连接通常在1-2秒后发生.. 尽管字段被广泛使用,Google IABHelper甚至不会将mService检查为null,甚至是几种异步方法。许多用户在断开连接时都会获得NPE。 我想修补IabHelper。问题是如何......
在异步方法中使用字段mService时,处理断开连接的正确方法是什么?只需忽略onServiceDisconnected并获取RemoteExceptions?我想到了wait-notify方法,但不能保证重新连接会发生。 任何想法都受到欢迎。
答案 0 :(得分:2)
IabHelper示例已更新,以修复几个月前的一些错误,所以首先要确保您拥有最新版本。我已经使用了早期的版本并对我自己进行了各种修复,所以我不能说最新版本是否真的解决了这个问题。
这是一段时间后提出的问题:
https://code.google.com/p/android/issues/detail?id=41610
一般方法是复制和编辑IabHelper,并在您自己的副本中,测试launchPurchaseFlow()顶部的空值。像这样:
//If the service has somehow disconnected, then we cannot make the purchase
if(mService == null) {
result = new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Unable to buy item because billing service disconnected unexpectedly.");
if (listener != null) listener.onIabPurchaseFinished(result, null);
flagEndAsync();
return;
}
...
此外,在onServiceDisconnected()结束时,您将希望中止可能因服务断开而中断的任何异步操作。像这样:
boolean asyncWasInProgress = mAsyncInProgress;
if(asyncWasInProgress) {
flagEndAsync();
}
希望有帮助。 IabHelper(至少我使用的早期版本)有很多错误,因此您可能会遇到这类问题,而且当您这样做时,需要修复此类问题。
答案 1 :(得分:0)
我重构了谷歌的下载的V3包装类IabHelper以摆脱空指针异常。我在项目中没有看到锁定/同步问题的一个方面。没有并行处理,除非与计费服务的连接中断,并且将对象设置为空不会花费很长时间。
可以从github下载结果。
我也可以自由地减少一些方法的长度并将它们分开。我是方法体不应超过屏幕或页面的方法的粉丝;有助于使代码更具可读性。