Как отслеживать LiveData, созданные Сервисом, из UI/MainActivity/Fragments?

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

Я хотел бы улучшить это, чтобы использовать MutableLiveData, что-то вроде этого.

class MyService : Service() {
    private var mMyServiceCreatedData = MutableLiveData<String>()
    private var mData = ""

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        ....
        mData = someData
        mMyServiceCreatedData.postValue(mData)
    }
}

Я понимаю, что есть viewModel, но в данном случае это служба, которая генерирует данные, а не viewModel, поэтому я не знаю, как она работает для службы. Можно ли наблюдать за данными, созданными из службы, в пользовательском интерфейсе/MainActivity/Fragments?


comment
Не могли бы вы просто поместить это в companion object, а затем сделать MyService.mMyServiceCreatedData там, где хотите?   -  person tyczj    schedule 28.09.2020
comment
@tyczj никогда так не делай. Вот как это должно быть сделано.   -  person Martin Marconcini    schedule 28.09.2020


Ответы (1)


Есть много разных подходов к этому, поэтому я не буду вдаваться в подробности; Stack Overflow не построен вокруг этого.

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

Если вам не нравится режим LocalBroadcast, вы можете:

  1. Служба сохраняет значение в репозитории вместо того, чтобы испускать/отправлять значение.
  2. Репозиторий выдает flow или предоставляет LiveData (мне не нравятся liveData в репозиториях, но это нормально).
  3. ViewModel (и UI/Fragment/Act) в конечном итоге подпишется на этот репозиторий (тот же экземпляр, я предполагаю, что у вас есть внедрение зависимостей или вы передаете свои ссылки в любом случае), когда он находится в области действия.

Это разделяет все части и позволяет им работать независимо друг от друга.

В крайнем случае, вы всегда можете bind обслуживать свою деятельность, но это - я полагаю - вариант использования, отличный от этого.

person Martin Marconcini    schedule 28.09.2020
comment
В моем случае использование репозитория является излишним и добавляет сложности, поскольку мои данные состоят всего из 4 строк, если быть точным. Я также пробовал использовать DataStore, но по какой-то причине изменения данных в DataStore не отображаются в пользовательском интерфейсе GlobalScope.launch { dataStoreManager.storeData(someData) } dataStoreManager.data1Flow.asLiveData().observe(this, { }) - person joke4me; 28.09.2020
comment
Думаю, лучше остаться с LocalBroadcast - person joke4me; 28.09.2020
comment
Честно говоря, если у вас есть 4 строки, продолжайте использовать LocalBroadcast :) Вы даже можете использовать простой держатель значений для всех 4 строк и транслировать их (все 4) одновременно, один раз или аналогично. - person Martin Marconcini; 28.09.2020
comment
При необходимости отправлять широковещательную рассылку из службы в пользовательский интерфейс, слушать и действовать, а затем отправлять обратно клики пользовательского интерфейса в виде широковещательной передачи из пользовательского интерфейса в службу, а затем действовать, код может стать довольно беспорядочным :-) В любом случае, спасибо за ваш вклад, это очень помогает! - person joke4me; 28.09.2020
comment
Это может стать грязным и раздражающим, но тогда вопрос смещается в сторону следующего: действительно ли вам нужен ваш сервис для перехвата всех этих событий? Услугу следует использовать только в крайнем случае в сети. Если ваша работа зависит от присутствия пользовательского интерфейса, то служба вряд ли будет лучшим выбором, если, с другой стороны, вам не нужен пользовательский интерфейс, вам не следует заботиться о событиях пользовательского интерфейса в вашей службе, тех, должен обрабатываться в другом месте, и к нему должны всплывать только полезные для службы действия. Возможно, переосмысление того, как вы его используете, может помочь отменить запутывание кода :) - person Martin Marconcini; 28.09.2020