Android LiveData: как избежать переноса данных из базы данных при повторном открытии приложения из фона? - PullRequest
0 голосов
/ 08 февраля 2020

Мое Android приложение прослушивает базу данных Firebase. Всякий раз, когда моя активность становится неактивной, я прекращаю прослушивание, а когда активность снова становится активной, я возобновляю прослушивание. Это делается с использованием LiveData и методов onActive и onInactive, как показано ниже:

@Override
protected void onActive() {
    Log.d(LOG_TAG, "onActive");
    query.addValueEventListener(listener);
}

@Override
protected void onInactive() {
    Log.d(LOG_TAG, "onInactive");
    query.removeEventListener(listener);
}

Используя отладчик, я заметил, что когда я нажимаю кнопку «Назад» и закрываю приложение, метод onInactive получает называется, и приложение идет в фоновом режиме. Когда я снова открываю приложение, выбирая его среди приложений в фоновом режиме, вызывается метод onActive. Однако в этом случае все мои данные перечитываются из базы данных, которая будет использовать пропускную способность данных.

Мой вопрос:

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

Спасибо

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Самый простой способ уменьшить загрузку данных в этом случае - включить сохранение диска в клиенте Firebase.

При включенном постоянстве диска клиент Firebase будет записывать любые данные, которые он получает с сервера, в локальный дисковый кеш, очищая старые данные, если кеш становится слишком большим.

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

1 голос
/ 08 февраля 2020

То, что вам нужно будет сделать, это установить «тайм-аут» своего рода для ваших LiveData так, чтобы он откладывал неактивность на столько времени, сколько вы считаете нужным.

Я реализовал « LingeringLiveData *» 1004 * "суперкласс именно для этой ситуации. Вы можете увидеть это в моем проекте на GitHub. Он написан на Kotlin, но вы сможете без проблем перенести его на Java.

Подклассы должны предоставлять реализации для startLingering и stopLingering, которые отражают то, что вы обычно делаете в onActive и onInactive.

По сути, он устанавливает таймер для задержки вызова на endLingering после вызова onInactive, но только если onActive не был вызван до этого времени истекает. Это позволяет вам останавливать и запускать приложение без потери прослушивателя.

abstract class LingeringLiveData<T> : LiveData<T>() {

    companion object {
        private const val STOP_LISTENING_DELAY = 2000L
    }

    // To be fully unit-testable, this code should use an abstraction for
    // future work scheduling rather than Handler itself.
    private val handler = Handler()

    private var stopLingeringPending = false
    private val stopLingeringRunnable = StopLingeringRunnable()

    /**
     * Called during onActive, but only if it was not previously in a
     * "lingering" state.
     */
    abstract fun beginLingering()

    /**
     * Called two seconds after onInactive, but only if onActive is not
     * called during that time.
     */
    abstract fun endLingering()

    @CallSuper
    override fun onActive() {
        if (stopLingeringPending) {
            handler.removeCallbacks(stopLingeringRunnable)
        }
        else {
            beginLingering()
        }
        stopLingeringPending = false
    }

    @CallSuper
    override fun onInactive() {
        handler.postDelayed(stopLingeringRunnable, STOP_LISTENING_DELAY)
        stopLingeringPending = true
    }

    private inner class StopLingeringRunnable : Runnable {
        override fun run() {
            if (stopLingeringPending) {
                stopLingeringPending = false
                endLingering()
            }
        }
    }

}

Jetpack LiveData KTX теперь также предлагает удобный конструктор liveData , который принимает аналогичный параметр времени ожидания и запускает код в сопрограмме. Вы не сможете использовать вообще с Java, но о нем приятно знать.

...