我正在编写FirebaseFirestore快照侦听器的包装器,它使用RxKotlin Observable发出更改。
我编写了以下类,它使用create()方法创建observable,并在新数据快照可用时异步发出更改。
问题是我每次创建这个类的实例时都会泄漏内存而我会停止使用它。在不泄漏内存的情况下重写此类的最佳方法是什么?
有关如何创建可以从侦听器发出对象的Observable的任何资源都非常有用!
class DocumentRepository<T : ModelWithMetadata>(
path: List<String>,
private val model: Class<T>) {
private var documentReference: DocumentReference
val observable: Observable<T>
private var emitter: ObservableEmitter<T>? = null
private lateinit var item: T
init {
documentReference = FirebaseFirestore.getInstance().collection(path[0]).document(path[1])
for (i in 2..path.lastIndex step 2)
documentReference = documentReference.collection(path[i]).document(path[i + 1])
observable = Observable.create(this::listenChanges)
}
private fun listenChanges(emitter: ObservableEmitter<T>) {
this.emitter = emitter
documentReference.addSnapshotListener { documentSnapshot, _ ->
item = documentSnapshot.toObject(this.model)
this.emitter?.onNext(item)
}
}
fun get() {
emitter?.onNext(item)
}
fun put(item: T) {
item.updatedAt = TimeExtension.now()
documentReference.set(item)
}
fun delete(item: T) {
documentReference.delete()
}
}
答案 0 :(得分:1)
documentReference.addSnapshotListener
会返回ListenerRegistration
,您可以调用ListenerRegistration#remove
来删除侦听器。
而且,Emitter#setCancellable
允许您在取消订阅Observable
时清理资源,在这种情况下是分离监听器。
所以你的listenChanges
看起来像这样:
private fun listenChanges(emitter: ObservableEmitter<T>) {
this.emitter = emitter
val registration = documentReference.addSnapshotListener { documentSnapshot, _ ->
item = documentSnapshot.toObject(this.model)
this.emitter?.onNext(item)
}
emitter.setCancellable { registration.remove() }
}