我的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方法。但是,在这种情况下,我的所有数据都从数据库中重新读取,这将消耗数据带宽。
我的问题是:
什么是避免每次从后台返回应用程序时都重新读取数据的最佳方法?
谢谢
您需要做的是在LiveData上设置各种“超时”,以使其在您认为适当的延迟时间内保持不活动状态。
我正是在这种情况下实现了“ LingeringLiveData”超类。您可以在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 convenience constructor,它接受类似的超时参数并在协程中运行代码。您将无法从Java完全使用它,但是很高兴知道。
在这种情况下,减少数据下载的最简单方法是在Firebase客户端中将其下载到enable disk persistence。
启用磁盘持久性后,Firebase客户端会将从服务器获取的所有数据写入本地磁盘缓存,如果缓存太大,则会清除较旧的数据。
当客户端重新启动时,客户端将首先从磁盘读取数据,然后仅使用所谓的增量同步从服务器请求更新。尽管此增量同步仍在传输数据,但通常应大大少于您收听的位置的总数据。