当 Observable.create() 发出侦听器对象时避免内存泄漏
Avoid memory leak when Observable.create() to emit listener objects
我正在围绕 FirebaseFirestore 快照侦听器编写一个包装器,它使用 RxKotlin Observable 发出更改。
我编写了以下 class,它使用 create() 方法创建可观察对象并在新数据快照可用时异步发出更改。
问题是每次我创建此 class 的实例并停止使用它时都会泄漏内存。在不泄漏内存的情况下重写此 class 的最佳方法是什么?
关于如何创建可以从侦听器发出对象的 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()
}
}
documentReference.addSnapshotListener
returns 一个 ListenerRegistration
which allows you to call 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() }
}
我正在围绕 FirebaseFirestore 快照侦听器编写一个包装器,它使用 RxKotlin Observable 发出更改。
我编写了以下 class,它使用 create() 方法创建可观察对象并在新数据快照可用时异步发出更改。
问题是每次我创建此 class 的实例并停止使用它时都会泄漏内存。在不泄漏内存的情况下重写此 class 的最佳方法是什么?
关于如何创建可以从侦听器发出对象的 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()
}
}
documentReference.addSnapshotListener
returns 一个 ListenerRegistration
which allows you to call 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() }
}