android - Android LiveData:如何避免从后台重新打开应用程序时从数据库传输数据?
问题描述
我的 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
afteronInactive
的调用,但前提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 中使用,但很高兴知道这一点。
推荐阅读
- sql - Oracle中的UNION ALL查询导致错误
- javascript - 可重用复选框组件中的角度绑定字符串值
- ios - 从 DispatchQueue Swift 内部返回
- .net - VS2019 + Dotnet Framework 4.7.2中的Nuget包安装问题
- ios - Xcode UI 测试无法找到密码TextField
- python - 我想以特定格式输出这个 python 问题,但不知道如何格式化?
- node.js - Discord Bot Reaction Collector with Javascript
- python - 如何在 Python Flask 中为 API 安全地保存多个凭据?
- python - 使用 Kubernetes 部署的 Flask:socket.gaierror: [Errno -2] Name or service not known
- node.js - 如何设置 vscode intellisense 以使用 nvm