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

时间:2020-08-01 04:22:03

标签: android firebase kotlin android-lifecycle android-viewmodel

在Android OS中,由于各种配置更改(例如方向更改),活动被销毁并重新创建。但这也会导致更多的成本-例如重新提取数据以显示UI。因此,ViewModel的开发目的是在活动被真正破坏之前保持数据存在-在配置更改期间保持数据安全。

我一直在我的应用程序中使用Firebase实时数据库,并且以Firebase SDK中的ChildEventListener闻名。由于使用ViewModel有很多优点-我很想在我的应用程序中使用它。我已经阅读了各种资源,以及有关ViewModel体系结构和Firebase的博客:但是它们仅使用ValueEvent Listeners。我正在应用程序中显示RecyclerViewChildEventListener是此的最佳选择。

我想使用具有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方法为止。

所以我的问题是,如何从此处断开处于非活动状态的侦听器?

0 个答案:

没有答案