2014-01-23 5 views
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 всегда устанавливается на нуль? Неправильно ли просто игнорировать обратный вызов onServiceConnected? По моему опыту пересоединение обычно происходит через 1-2 секунды. Google IABHelper даже не проверяет mService на нуль, несмотря на широко используемое поле, даже несколько асинхронных методов. И многие мои пользователи получают NPE в случае разъединения. Я хочу установить IabHelper. Вопрос в том, как ..

Что такое правильный способ справиться с disconnession, когда поле mService используется внутри асинхронных методов? Просто игнорируйте onServiceDisconnected и получите RemoteExceptions? Я подумал о подходе к уведомлению о ожиданиях, но нет гарантии, что произойдет пересоединение. Любые идеи приветствуются.

ответ

2

Пример IabHelper обновлен, чтобы исправить несколько ошибок пару месяцев назад, поэтому прежде всего убедитесь, что у вас установлена ​​последняя версия. Я использовал более раннюю версию и сделал несколько собственных исправлений, поэтому не могу сказать, действительно ли последнее исправляет это.

Вот вопрос, который был подан некоторое время назад в отношении его:

https://code.google.com/p/android/issues/detail?id=41610

Общий подход будет копировать и редактировать IabHelper, и в вашей собственной копии, тест на нулевое значение на top of startPurchaseFlow(). Что-то вроде этого:

//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 (по крайней мере, более ранняя версия, которую я использовал) имеет множество ошибок, поэтому вы можете столкнуться с подобными вещами, и такие проблемы необходимо будет устранить, когда вы это сделаете.

+0

Спасибо за ваш ответ. Упомянутая проблема - моя собственная :) – akarimova

+0

Но проверка нулевого значения в многопоточной среде - неправильный путь. В любом случае, благодарю Вас. – akarimova

+0

В документации для ServiceConnection указано, что «Как и многие обратные вызовы из системы, методы этого класса вызываются из основного потока вашего процесса». Таким образом, проблемы многопоточного исполнения не должны применяться в этом случае. Объект ServiceConnection остается активным, и если и когда услуга будет восстановлена, будет вызван метод onServiceConnected(), и mService будет установлен в ненулевое значение, и вы будете готовы снова обрабатывать покупки. http://developer.android.com/reference/android/content/ServiceConnection.html – Carl

0

Я реорганизовал загруженный класс оболочки V3 IabHelper Google, чтобы избавиться от исключений из нулевого указателя. Я не вижу аспекта проблем с блокировкой/синхронизацией в моем проекте. Нет параллельной обработки, кроме случаев, когда соединение с биллинговой службой прерывается, а установка объекта на нуль не займет много времени.

Результат может быть загружен с github.

Я также счел свободным уменьшить длину некоторых методов и разделить их. Я поклонник подхода, в котором тело методов не должно превышать экран или страницу; помогает сделать код более читаемым.