android - 将 Firebase 数据库 ChildEventListener 与 ViewModel 一起使用的正确方法是什么?
问题描述
在 Android 操作系统中,由于各种配置更改,例如方向更改,活动会被销毁并重新创建。但这也会导致更多的成本 - 例如重新获取数据以显示 UI。因此,ViewModel
开发用于在活动真正销毁之前保持数据存在 - 在配置更改期间保持安全。
我一直在我的应用程序中使用 Firebase 实时数据库,并且我ChildEventListener
在 Firebase SDK 中的存在非常有名。由于使用有很多优点ViewModel
- 我有兴趣在我的应用程序中使用它。我已经阅读了各种资源、关于ViewModel
架构以及 Firebase 的博客:但它们仅使用 ValueEvent 侦听器。我RecyclerView
在应用程序中显示,ChildEventListener
是一个完美的候选人。
我想维护一个使用ChildEventListener
架构ViewModel
的列表。我已经编写了代码来使用ViewModel
.
class DataViewModel : ViewModel() {
private var listenerRemovePending = false
private val listener = MyChildEventListener()
private val handler = Handler(Looper.getMainLooper())
private lateinit var dataListRef: DatabaseReference
var data: MutableLiveData<ArrayList<DataModel>> = MutableLiveData()
val dataList: ArrayList<DataModel> = arrayListOf()
fun getData(userId: String): LiveData<ArrayList<DataModel>> {
dataListRef =
FirebaseDatabase.getInstance().getReference("/data/$userId/data")
dataListRef.addChildEventListener(object : ChildEventListener {
override fun onCancelled(databaseError: DatabaseError) {
Log.e(
LOG_TAG,
"Can't listen to query :dataListRef",
databaseError.toException()
)
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
if (snapshot.exists()) {
val item: DataModel? =
snapshot.getValue(DataModel::class.java)
if (item != null) {
dataList.add(item)
}
data.value = dataList
}
}
override fun onChildRemoved(snapshot: DataSnapshot) {
TODO("Not yet implemented")
}
})
return data
}
companion object {
private const val LOG_TAG = "DataViewModel"
}
}
我对它的结果很满意。ChildEventListener
但这是一个主要问题 -如果没有观察者(活动未激活),我希望将其分离。目前,此侦听器处于活动状态,直到活动结束 - 这ViewModel
将保持其侦听器连接,直到调用 Activity 的onDestroy
方法。
所以我的问题是如何从这里分离非活动状态的侦听器?
解决方案
您应该在 ViewModel 类中覆盖 onCleared() 函数。但是如果你想使用 MVVM 模式,你的网络请求应该在 SomRequestRemoteDataSource 中。
override fun onCleared() {
super.onCleared()
dataListRef.removeEventListener(yourChildListener)
}
推荐阅读
- javascript - 使用 webpack 在导入的 css 文件中包含图像
- windows - Windows 如何在没有位置无关代码的情况下处理加载到内存中的多个 DLL?
- chart.js - 在悬停弹出Chart.js中y轴数据值后显示字符
- python - Python - Beautiful Soup - 删除
标记前的值 - c# - 如何从 ASP.Net/C# Webforms 中的任何电子邮件地址发送电子邮件
- sql - 多个多对多关系
- c++ - C++ 不能将 ExpressJS API 检索到的 GET 请求中的响应字符串用于打印以外的任何内容
- javascript - 当我从 API 检索数据但它在 Angular 中显示为对象时
- php - wordpress customize_register 上的多个函数?
- mysql - 来自审计跟踪数据库的 Mysql 用户活动报告