Android: остановка службы Bonjour после запуска родительского процесса

Мое приложение - это, по сути, фоновый сервис, который должен периодически регистрировать NSD оказание услуг (Bonjour service), чтобы разрешить обнаружение сервера сокетов, запускаемого основным фоновым сервисом (или приложением).

Если я правильно читаю документ службы Android Bonjour, вот как вы начинаете Bonjour услуга (сокращенно для краткости):

mNsdManager = Context.getSystemService(Context.NSD_SERVICE);
mDiscoveryListener = new NsdManager.DiscoveryListener()
mNsdManager.discoverServices(
        SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);

... и вот как ты это прекратишь:

mNsdManager.unregisterService(mRegistrationListener);

Вот часть, которую я не могу обернуть головой: если основной сервис внезапно выходит из строя, любой Bonjour служба, которая была зарегистрирована во время сбоя, продолжает работать, даже если у нее больше нет цели (сервер сокетов, который он помогает обнаружить, больше не существует).

Я не могу очистить зомби Bonjour услуги, когда основной сервис перезапускается, потому что mRegistrationListener служба была первоначально зарегистрирована, также больше не существует.

Я подозреваю, что выбрал неправильный подход: как мне убедиться, что я не оставляю беспорядок зомби Bonjour службы позади после того, как основной сервис упал?

2 ответа

Решение

Не специфично для Android Bonjour, вы можете попытаться обработать сбой, настроив свой сервис, как указано в ответе здесь: Могу ли я вызвать метод до того, как мое приложение выйдет из строя

Если вы не можете настроить это для вызова unregisterService, вы должны иметь возможность настроить его на использование API killBackgroundProcesses ActivityManager. Это требует добавления разрешения к вашему манифесту:

android.permission.KILL_BACKGROUND_PROCESSES

Если я вас правильно понял, основной сервис (тот, что с сокетом сервера) регистрирует / отменяет регистрацию Nsd служба в то время как фоновая служба запускает / останавливает обнаружение Nsd оказание услуг. Я думаю, что это то, что вы делаете, поэтому ваш "подход" правильный.

Что касается проблемы, я должен приветствовать вас на Android Nsd, Есть много ошибок с фреймворком (среди которых вы можете найти свою проблему), что на Android 6.0 еще не исправлено, поэтому разработчики использовали вместо этого другие фреймворки.

Возвращаясь к вопросу, вы можете попробовать UncaughtExceptionHandlerпросто имейте в виду, что все обратные вызовы вызываются системой асинхронно, и вы можете получить NPE когда он звонит mRegistrationListener.onServiceUnregistered()потому что, как вы сказали, "его больше нет вокруг".

Что касается сервисной очистки, то теоретически это возможно, но только после NsdManager настройка исходного кода (модификатор доступа нескольких методов должен быть изменен для достижения, а затем отмены регистрации mRegistrationListener из другого процесса, который приведет к удалению его из карты слушателя NsdManager). Но это не имеет никакого смысла, если приложение будет опубликовано на рынке.

Есть еще один обходной путь, с которым вы можете попробовать / поэкспериментировать. Если я правильно помню (может ошибаться), необходимая очистка происходит при отключении Nsd, Я пробовал через adb:

// Disable
adb shell service call servicediscovery 2
// Enable
adb shell service call servicediscovery 2 i32 1

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

Учитывая killBackgroundProcesses() Метод, предложенный @thril, принимает строку с именем пакета приложения в качестве параметра. Но servicediscovery это не приложение, это системный сервис. Кроме того, вы можете попытаться убить процесс (хотя я не знаю, какой именно) во время выполнения, но будьте осторожны, вы должны выяснить, какое влияние он оказывает на систему, и быть уверенным, что служба будет запущена снова при необходимости (автоматически по системе или вручную). Опять же, для этого нужен рут.

Подводя итог, прежде чем продолжить NsdЯ настоятельно рекомендую сделать поиск относительно его функциональности / ошибок, чтобы избежать возможной траты вашего времени и усилий. Некоторые ссылки в дополнение к ссылке, приведенной выше:

  1. Сообщение об утере устройства NSD не получено при отключении Wi-Fi
  2. NsdManager не останавливает обнаружение службы

PS Лично я, после борьбы с множественными Nsd ошибки в фреймворке, в итоге я написал собственный фреймворк

Другие вопросы по тегам