#android #service
#Android #Обслуживание
Вопрос:
Это скорее вопрос о внутренностях Android для людей, которые сталкивались с подобными сомнениями в прошлом.
Вопрос довольно прост по сути:
предполагая, что у меня есть служба привязки, которая предоставляет определенные функциональные возможности приложениям, запущенным в других процессах, — как я могу узнать, есть ли вызывающая сторона, запрашивающая функциональность, все еще там?
предположим, у меня есть удаленная служба, которая реализует удаленные обратные вызовы, как упоминалось здесь, как я могу быть уверен, что все еще существует класс для получения обратного вызова? как выполняется очистка? автоматически ли закрывается привязка при выходе из приложения / сбое, как это происходит с открытыми файлами или сокетами?
и, наконец:
если удаленное приложение выйдет из строя без привязки к моей службе, будет ли оно продолжать работать, даже если это было последнее приложение, использующее службу?
спасибо за все советы, ребята, цените это.
Ответ №1:
Я только что протестировал это, и даже если внешний компонент пропустит ServiceConnection, не выполнив привязку, Android отключит службу (при условии, что она не была запущена с помощью startService и не привязана к другому месту). В этом случае будут вызваны onUnbind и onDestroy.
Что касается определения того, работают ли компоненты, зарегистрировавшие обратные вызовы, я считаю, что CommonsWare прав в том, что вам следует просто попробовать обратный вызов. Тем не менее, вы должны иметь возможность активировать вызывающий компонент и запустить его обратно.
Существует два вида желаемого поведения при обратном вызове, если внешний компонент не работает (так что обычный обратный вызов завершится неудачей):
- Внешний компонент должен получать обратный вызов от вашей службы только в том случае, если рассматриваемый компонент все еще активен. В этом случае просто проглотите (и зарегистрируйте) исключение, вызванное попыткой вызвать недействительный обратный вызов.
- Внешний компонент, который больше не активен, ДОЛЖЕН быть активирован, когда ваша служба пытается выполнить обратный вызов. Поскольку вы не можете сделать это с помощью обычных методов обратного вызова, вам нужно будет запустить какое-либо намерение, чтобы разбудить мертвый компонент. Самый простой способ сделать это — предоставить компоненту методы для регистрации PendingIntent в вашем сервисе. Если обычный обратный вызов завершается неудачей, просто отключите PendingIntent. Внешний компонент (который должен был зарегистрироваться в качестве получателя для соответствующего намерения) проснется и соответствующим образом отреагирует на намерение, возможно, путем повторной привязки и вызова дополнительных методов для получения результата неудачного обратного вызова. Предостережение заключается в том, что если вы разрешите вызывающим абонентам умереть, и они будут ожидать пробуждения, вам потребуется, чтобы служба запустилась сама через startService () и остановилась соответствующим образом, поскольку в противном случае вас могут забрать во время выполнения запрошенной работы перед запуском PendingIntent
Комментарии:
1. Огромное спасибо. Итак, я думаю, что конечным способом было бы время от времени «сердцебиение» моих слушателей и просто очищать тех, кто вызывает исключение. это звучит довольно хорошо, в значительной степени похоже на сеть. также полезно знать, что Android сам позаботится об удалении мертвых привязок. это в значительной степени устраняет проблему запуска процесса, когда в нем никто не заинтересован.
2. Нет необходимости в сердцебиениях, IMO. Смотрите мои изменения в ответе для одного из способов сделать это.
Ответ №2:
предполагая, что у меня есть служба привязки, которая предоставляет определенные функциональные возможности приложениям, запущенным в других процессах, — как я могу узнать, есть ли вызывающая сторона, запрашивающая функциональность, все еще там?
Ты этого не делаешь, AFAIK.
предположим, у меня есть удаленная служба, которая реализует удаленные обратные вызовы, как упомянуто здесь, как я могу быть уверен, что все еще существует класс для получения обратного вызова?
Вы должны получить RemoteObjectException
, если объект обратного вызова больше не используется (например, клиент ушел).
как выполняется очистка?
Я понятия не имею, что это означает в данном контексте, извините.
автоматически ли закрывается привязка при выходе из приложения / сбое, как это происходит с открытыми файлами или сокетами?
Да, хотя вы не уведомлены об этом факте в сервисе.
если удаленное приложение выйдет из строя без привязки к моей службе, будет ли оно продолжать работать, даже если это было последнее приложение, использующее службу?
Я не знаю наверняка. Я бы надеялся, что Android обнаружит это и остановит службу, но я этого не пробовал.