首页 > 解决方案 > 在 LiveData-returning 函数中删除 Firestore 快照侦听器

问题描述

我正在尝试优化我的应用程序的性能,我注意到我没有从我的存储库中删除 Firestore 侦听器。

我的存储库有许多返回 a 的函数,LiveData然后通过 Transformations fromViewModels和 view 进行观察。

一次性操作绝对可以正常工作(上传、删除等),但永久侦听器不会在活动完成时收集垃圾。

现在存储库中的函数如下所示:

// [...]
class Repository {   
  // [...]
  fun retrieveCode() {
  val observable = MutableLiveData<Code>()
  val reference = 
    FirebaseFirestore.getInstance().collection(/**/).document(/**/)

  reference
    .addSnapshotListener { snapshot, exception -> 
      if(exception != null) {
        observable.value = null
      }

      if(snapshot != null {
        observable.value = snapshot.//[convert to object]
      }
   }

   return observable
  }
}

我找到了一种解决方法,它是创建一个自定义LiveData对象,当它变为非活动状态时处理侦听器的移除,如下所示:

class CodeLiveData(private val reference: DocumentReference): 
  LiveData<Code>(), EventListener<DocumentSnapshot>{
  private var registration: ListenerRegistration? = null

  override fun onEvent(snapshot: DocumentSnapshot?, 
    exception: FirebaseFirestoreException?) {
    if(exception != null) {
      this.value = null
    }

    if(snapshot != null) {
      this.value = snapshot.//[convert to object]
    }
  }

  override fun onActive() {
    super.onActive()
    registration = reference.addSnapshotListener(this)
  }

  override fun onInactive() {
    super.onInactive()
    registration?.remove()
  }
}

有没有办法在不创建自定义类的情况下解决这个问题,而是通过改进类似于第一个示例的功能?

谢谢,

埃米利奥

标签: firebasekotlingoogle-cloud-firestore

解决方案


有两种方法可以实现这一目标。第一个是停止监听变化,这可以通过在你的对象上onStop()调用remove()函数来在你的函数中完成,ListenerRegistration如下所示:

if (registration != null) {
    registration.remove();
}

该方法是将您的活动作为函数中的第一个参数传递addSnapshotListener(),因此 Firestore 可以在活动停止时自动清理侦听器。

var registration = dataDocumentReference
        .addSnapshotListener(yourActivity, listener)

推荐阅读