bindService, unbindService, сценарии для Android и не для солнечного дня

#android #service

#Android #Обслуживание

Вопрос:

Это скорее вопрос о внутренностях Android для людей, которые сталкивались с подобными сомнениями в прошлом.

Вопрос довольно прост по сути:

предполагая, что у меня есть служба привязки, которая предоставляет определенные функциональные возможности приложениям, запущенным в других процессах, — как я могу узнать, есть ли вызывающая сторона, запрашивающая функциональность, все еще там?

предположим, у меня есть удаленная служба, которая реализует удаленные обратные вызовы, как упоминалось здесь, как я могу быть уверен, что все еще существует класс для получения обратного вызова? как выполняется очистка? автоматически ли закрывается привязка при выходе из приложения / сбое, как это происходит с открытыми файлами или сокетами?

и, наконец:

если удаленное приложение выйдет из строя без привязки к моей службе, будет ли оно продолжать работать, даже если это было последнее приложение, использующее службу?

спасибо за все советы, ребята, цените это.

Ответ №1:

Я только что протестировал это, и даже если внешний компонент пропустит ServiceConnection, не выполнив привязку, Android отключит службу (при условии, что она не была запущена с помощью startService и не привязана к другому месту). В этом случае будут вызваны onUnbind и onDestroy.

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

Существует два вида желаемого поведения при обратном вызове, если внешний компонент не работает (так что обычный обратный вызов завершится неудачей):

  1. Внешний компонент должен получать обратный вызов от вашей службы только в том случае, если рассматриваемый компонент все еще активен. В этом случае просто проглотите (и зарегистрируйте) исключение, вызванное попыткой вызвать недействительный обратный вызов.
  2. Внешний компонент, который больше не активен, ДОЛЖЕН быть активирован, когда ваша служба пытается выполнить обратный вызов. Поскольку вы не можете сделать это с помощью обычных методов обратного вызова, вам нужно будет запустить какое-либо намерение, чтобы разбудить мертвый компонент. Самый простой способ сделать это — предоставить компоненту методы для регистрации PendingIntent в вашем сервисе. Если обычный обратный вызов завершается неудачей, просто отключите PendingIntent. Внешний компонент (который должен был зарегистрироваться в качестве получателя для соответствующего намерения) проснется и соответствующим образом отреагирует на намерение, возможно, путем повторной привязки и вызова дополнительных методов для получения результата неудачного обратного вызова. Предостережение заключается в том, что если вы разрешите вызывающим абонентам умереть, и они будут ожидать пробуждения, вам потребуется, чтобы служба запустилась сама через startService () и остановилась соответствующим образом, поскольку в противном случае вас могут забрать во время выполнения запрошенной работы перед запуском PendingIntent

Комментарии:

1. Огромное спасибо. Итак, я думаю, что конечным способом было бы время от времени «сердцебиение» моих слушателей и просто очищать тех, кто вызывает исключение. это звучит довольно хорошо, в значительной степени похоже на сеть. также полезно знать, что Android сам позаботится об удалении мертвых привязок. это в значительной степени устраняет проблему запуска процесса, когда в нем никто не заинтересован.

2. Нет необходимости в сердцебиениях, IMO. Смотрите мои изменения в ответе для одного из способов сделать это.

Ответ №2:

предполагая, что у меня есть служба привязки, которая предоставляет определенные функциональные возможности приложениям, запущенным в других процессах, — как я могу узнать, есть ли вызывающая сторона, запрашивающая функциональность, все еще там?

Ты этого не делаешь, AFAIK.

предположим, у меня есть удаленная служба, которая реализует удаленные обратные вызовы, как упомянуто здесь, как я могу быть уверен, что все еще существует класс для получения обратного вызова?

Вы должны получить RemoteObjectException , если объект обратного вызова больше не используется (например, клиент ушел).

как выполняется очистка?

Я понятия не имею, что это означает в данном контексте, извините.

автоматически ли закрывается привязка при выходе из приложения / сбое, как это происходит с открытыми файлами или сокетами?

Да, хотя вы не уведомлены об этом факте в сервисе.

если удаленное приложение выйдет из строя без привязки к моей службе, будет ли оно продолжать работать, даже если это было последнее приложение, использующее службу?

Я не знаю наверняка. Я бы надеялся, что Android обнаружит это и остановит службу, но я этого не пробовал.