3

几乎所有使用远程服务的示例都包含此类代码(此代码取自 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 秒后发生。尽管该字段被广泛使用,谷歌 IABHelper 甚至不检查 mService 是否为空,甚至是几种异步方法。在断开连接的情况下,我的许多用户都会获得 NPE。我想修补 IabHelper。问题是如何..

在异步方法中使用字段 mService 时,处理断开连接的正确方法是什么?只需忽略 onServiceDisconnected 并获取 RemoteExceptions?我考虑过等待通知方法,但不能保证会发生重新连接。欢迎任何想法。

4

2 回答 2

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(至少我使用的早期版本)有许多错误,因此您可能会遇到这种事情,并且当您这样做时需要修复这些问题。

于 2014-02-04T01:03:26.397 回答
0

我重构了谷歌下载的 V3 包装类 IabHelper 以摆脱空指针异常。我在我的项目中没有看到锁定/同步问题的一个方面。除了与 Billing 服务的连接中断时,没有并行处理,并且将对象设置为 null 不会花费很长时间。

结果可以从github下载。

我也可以随意减少一些方法的长度并将它们拆分。我喜欢方法主体不应超过屏幕或页面的方法。有助于使代码更具可读性。

于 2017-01-12T19:07:31.553 回答