将Firebase Database ChildEventListener与ViewModel一起使用的正确方法是什么



在Android操作系统中,由于各种配置更改,如方向更改,活动会被销毁并重新创建。但这也会导致更高的成本,比如重新蚀刻数据以显示UI。因此,开发ViewModel是为了在活动真正被破坏之前保持数据的存在——在配置更改期间保持数据的安全。

我一直在我的应用程序中使用Firebase实时数据库,我对Firebase SDK中的ChildEventListener非常熟悉。由于使用ViewModel有很多优点,我很有兴趣在我的应用程序中使用它。我读过各种关于ViewModel架构和Firebase的来源和博客:但它们只使用ValueEvent监听器。我在应用程序中显示RecyclerView,而ChildEventListener就是一个完美的候选者。

我想使用ChildEventListenerViewModel架构来维护一个列表。我已经编写了使用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)
}

相关内容

  • 没有找到相关文章

最新更新