处理远程服务器断开的正确方法是什么?

时间:2014-01-23 20:00:14

标签: android android-service android-service-binding

几乎所有使用远程服务的例子都包含这样的代码(这个代码来自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方法,但不能保证重新连接会发生。 任何想法都受到欢迎。

2 个答案:

答案 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下载结果。

我也可以自由地减少一些方法的长度并将它们分开。我是方法体不应超过屏幕或页面的方法的粉丝;有助于使代码更具可读性。