Слушатель уже используется (Service Discovery)
Я не могу разрешить одну службу, пока решается другая? Если это то, что означает ошибка... Как ждать, пока она не будет устранена?
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service found. " + service);
if (service.getServiceType().equals(SERVICE_TYPE)) {
if (service.getServiceName().contains(mServiceName)) {
mNsdManager.resolveService(service, mResolveListener);
}
}
}
java.lang.IllegalArgumentException: слушатель уже используется на android.net.nsd.NsdManager.resolveService(NsdManager.java:613) на com.example.miguel.broadcast.LocalService$2.onServiceFound(LocalService.java:145)
3 ответа
Вам не нужно ждать! Если вы посмотрите на javadocs для resolService(NsdServiceInfo serviceInfo, NsdManager.ResolveListener listener), то вы заметите, что для слушателя параметра он говорит "получать обратный вызов при успехе или неудаче. Не может быть пустым. Не может использоваться для активной службы". разрешающая способность."
Поэтому, чтобы это работало, просто сделайте следующее:
mNsdManager.resolveService(service, new MyResolveListener());
Где MyResolveListener находится:
private class MyResolveListener implements NsdManager.ResolveListener {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
//your code
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
//your code
}
}
надеюсь это поможет:)
У меня тоже была эта проблема, и я следил за реализацией Android NsdHelper, изложенной здесь в NsdChat. В этом примере показано создание отдельного mResolveListener NsdManager.ResolveListener в классе NsdHelper и использование этого ResolveListener для всех вызовов NsdManager.resolveService.
Отсюда я прочитал, что "для каждого активного запроса на регистрацию или обнаружение должен использоваться отдельный слушатель".
Поэтому вместо использования переменной класса mResolveListener создайте новый слушатель каждый раз, когда вы вызываете mNsdManager.resolveService:
@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
Log.d(TAG, "Service found: "+ serviceInfo);
if (serviceInfo.getServiceType().equals(SERVICE_TYPE)){
mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(TAG, "Resolve Failed: " + serviceInfo);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.i(TAG, "Service Resolved: " + serviceInfo);
}
});
}
}
Вы должны убедиться, что вы не передаете объект слушателя, который уже был зарегистрирован. Вы можете увидеть коммит, который привел к изменению этого поведения здесь.
Вот текст сообщения о коммите:
Документирование и применение правила "один запрос на слушателя"
API и реализация NsdManager подразумевают, что для каждого активного запроса на регистрацию или обнаружение должен использоваться отдельный прослушиватель. Это официально не задокументировано и не соблюдается должным образом, и происходят странные и непредсказуемые вещи, если приложение использует Listener для более чем одного запроса одновременно.
Обновите документацию, чтобы сделать это явным требованием.
Применять ограничение при отправке нового запроса на обработку; если прослушиватель уже используется для отслеживания активного запроса, выведите исключение.
Документируйте тот факт, что приложения должны отменить регистрацию служб и отменить обнаружение служб, когда приложение остановлено (в KitKat и предыдущих выпусках они утекут, если это не будет сделано).
Переупорядочить операцию "освобождение прослушивателя" до выполнения обратного вызова прослушивателя, чтобы после повторного вызова обратный вызов мог повторно использовать прослушиватель приложением - это устраняет условие состязания. Документируйте это.
Проход 2: опечатки, добавлена документация об уровне API, изменено использование явно определенного возвращаемого значения для "занятого слушателя".
Кроме того, просто предупреждение, что если вы загрузили пример проекта NsdChat с сайта разработчиков Android (т.е. NsdChat.zip
или что-то в этом роде), этот код проекта, вероятно, устарел.
Вместо этого попробуйте использовать последний код в основной ветке... вы можете скопировать и вставить его в свой пример проекта отсюда.