Подтвердить что ты не робот

Привязать услугу к активности или фрагменту?

Я работаю над приложением для музыкального плеера. У меня есть основная деятельность, которая имеет несколько фрагментов, каждый из которых отображает песни на альбоме устройства мудрым, художником мудрым и т.д.

У меня есть музыкальный сервис, который обрабатывает все воспроизведение и другие вещи.
Меня смущает связывание этой службы с различными фрагментами, которые у меня есть.
Прямо сейчас я связываю основную деятельность и каждый фрагмент индивидуально с сервисом, и его работа в значительной степени прекрасна. Но мне было интересно, действительно ли это лучшая практика? Есть ли способ связать основное действие с сервисом, а затем каким-то образом использовать его в своих дочерних фрагментах?
Возможно, мне не хватает элементарной концепции деятельности или фрагментов или служб. Так что, пожалуйста, помогите мне в этом отношении.
Я предполагаю, что это скорее концептуальный вопрос, поэтому никакой код не нужен. Но все же, если потребуется, пожалуйста, дайте мне знать.

РЕДАКТИРОВАТЬ:
Мой вопрос: что было бы лучшим способом связать службу с активностью с несколькими дочерними фрагментами (каждый из которых будет использовать эту службу)?

4b9b3361

Ответ 1

Привяжите Service к вашей деятельности, а не к Fragment. Описание вашего приложения, одно действие с несколькими Fragment, которые меняются местами и вне, делает это наиболее практичным (и действительно) практическим подходом.

При привязке Service к Activity вы привязываете свой жизненный цикл к циклу Activity. См. Связанные службы. Каждый раз, когда вы добавляете или удаляете Fragment в своей деятельности, который Fragment создается и уничтожается. Вы не хотите пытаться связать службу с этим процессом, потому что тогда вам придется создавать и уничтожать службу каждый раз, когда создается или уничтожается новый фрагмент.

Вместо этого привязывайтесь к хосту Activity. Затем вы можете взаимодействовать с хостом с вашими фрагментами с помощью интерфейса для доступа к связанным службам или с помощью Intent.

Ответ 2

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

Я вижу два основных преимущества при подключении из фрагмента:

  1. Подключение службы асинхронно, поэтому внутри фрагмента вы никогда не уверены, что служба, которую вы получаете от действия, не равна нулю. Это приведет вас, по крайней мере, к некоторым проверкам нулевого указателя и к некоторому механизму для обновления фрагмента как при его создании, так и при подключении службы (так что вы уверены, что будете отображать данные независимо от того, какой из двух событий произойдет первым).

  2. Вы не зависите от конкретной деятельности, в которой живут ваши фрагменты. Чтобы получить услугу из упражнения, я думаю, вы выполняете приведение к конкретному классу действия. Вы можете создать интерфейс, такой как BoundActivity с помощью метода, подобного getBoundService для получения сервиса от него, но я думаю, что это накладные расходы, учитывая преимущество пункта 1. А что, если у вас есть несколько сервисов?

ОБНОВИТЬ

Вот очень простой проект, показывающий это. https://github.com/ena1106/FragmentBoundServiceExample

Ответ 3

Вы можете получить доступ к своей деятельности из фрагмента getActivity()

Ответ 4

вы можете использовать лоток с использованием шаблона шины событий с этой библиотекой, шаблон публикации публикации/подписки eventbus. https://github.com/greenrobot/EventBus проверить сайт проекта для получения дополнительной информации.

вы можете отправлять события из/в службу в активный или фрагмент.

Ответ 5

ЕСЛИ вам нужно получить некоторые данные из вашей службы в ваш фрагмент в начале жизненного цикла фрагмента, onServiceConnected on activity еще не вызывается, в основном, когда вы вращаете свое устройство, и вы получите NPE. Я думаю, что это хорошая идея, пусть фрагмент создает свои собственные соединения, поскольку служба запускается с помощью startService(), а не с bindService().

Ответ 6

Я связываю службу в My Host Activity и передаю объект Ibinder через Bundle, который задан в аргументах.

и мой код может выглядеть так:

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //put service in bundle
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};

Ответ 7

Единственный метод, который я нашел надежным, - использовать загрузчик в Fragment:

  • создать Loader в фрагменте
  • используйте context для Loader (установите для activity в initLoader, когда вызывается фрагмент onCreate)
  • привязать службу в onStartLoading, используя ServiceConnection, которая вызывает forceLoad(), как только служба будет связана
  • необязательно регистрировать обратные вызовы в onStartLoading/onStopLoading
  • отвязать услугу в onStopLoading