在Android操作系统中,由于各种配置更改,如方向更改,活动会被销毁并重新创建。但这也会导致更高的成本,比如重新蚀刻数据以显示UI。因此,开发ViewModel
是为了在活动真正被破坏之前保持数据的存在——在配置更改期间保持数据的安全。
我一直在我的应用程序中使用Firebase实时数据库,我对Firebase SDK中的ChildEventListener
非常熟悉。由于使用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)
}