¿Debo cancelar la suscripción al utilizar rxbinding?
Hay cómo uso RxBinding con Kotlin:
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) reset_password_text_view.clicks().subscribe { presenter.showConfirmSecretQuestionBeforeResetPassword() } password_edit_text.textChanges().skip(1).subscribe { presenter.onPasswordChanged(it.toString()) } password_edit_text.editorActionEvents().subscribe { presenter.done(password_edit_text.text.toString()) } }
Observable.subscribe(action)
devuelve la Subscription
. ¿Debo mantenerlo como referencia y onPause()
suscripción onPause()
o onDestroy()
?
- Cómo crear un objeto retrofit.Response durante las pruebas de unidad con Retrofit 2
- Excepción de interrupción de subproceso en modo Multi-ventana
- RxAndroid textview eventos llamados automáticamente antes de cambios de texto eventos
- Dar un RxJava Observable algo a emitir de otro método
- ¿Por qué debounce () con toList () no funciona en RxAndroid?
Me gusta esto:
private lateinit var resetPasswordClicksSubs: Subscription override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) resetPasswordClicksSubs = reset_password_text_view.clicks().subscribe { presenter.showConfirmSecretQuestionBeforeResetPassword() } } override fun onDestroy() { super.onDestroy() resetPasswordClicksSubs.unsubscribe() }
- Unidad de prueba de la aplicación android con retrofit y rxjava
- ¿Cuál es la diferencia entre RxJava y Bolts?
- Manejo de listas con RxJava y Retrofit en android
- Manejador de errores por defecto de RxJava
- Error al resolver la dependencia de RXJava
- Retrofit 2 + Rxjava error de manipulación
- Android AsyncTask vs hilo + controlador vs rxjava
- RXJava - buffer observable 1 hasta que se pueda observar 2 emite un elemento
He hecho una pequeña configuración de prueba para averiguarlo. No es una aplicación para Android, sino que simula las relaciones de clase. Esto es lo que parece:
class Context class View(val context: Context) { lateinit var listener: () -> Unit fun onClick() = listener.invoke() } fun View.clicks() = Observable.fromEmitter<String>({ emitter -> listener = { emitter.onNext("Click") } }, Emitter.BackpressureMode.DROP) var ref: PhantomReference<Context>? = null fun main(args: Array<String>) { var c: Context? = Context() var view: View? = View(c!!) view!!.clicks().subscribe(::println) view.onClick() view = null val queue = ReferenceQueue<Context>() ref = PhantomReference(c, queue) c = null val t = thread { while (queue.remove(1000) == null) System.gc() } t.join() println("Collected") }
En este fragmento instancio una View
que contiene una referencia a un Context
. la vista tiene una devolución de llamada para los eventos de clic que envuelvo en un Observable
. Activar la devolución de llamada una vez, luego PhantomReference
todas las referencias a la View
y el Context
y sólo mantener una PhantomReference
. A continuación, en un hilo independiente espero hasta que se publique la instancia de Context
. Como puede ver, nunca me desinscribo del Observable
.
Si ejecuta el código, se imprimirá
Hacer clic
Recogido
y luego terminan probando que la referencia al Context
fue efectivamente liberada.
Lo que esto significa para ti
Como puede ver, un Observable
no impedirá que los objetos referenciados se recojan si las únicas referencias que tiene a él son circulares. Puede leer más sobre referencias circulares en esta pregunta .
Sin embargo, no siempre es así. Dependiendo de los operadores que utilice en la cadena observable, la referencia se puede filtrar, por ejemplo, por un programador o si se fusiona con un observable infinito, como interval()
. Explicarly unsubscribing de un observable es siempre una buena idea y usted puede reducir el boilerplate necesario usando algo como RxLifecycle .
Creo que Jake Wharton (el creador de la biblioteca) dio la mejor respuesta :
Trate a un RxView.clicks suscripto () (o cualquier observable de esta biblioteca para esa materia) como usted haría la referencia de la visión sí mismo. Si lo pasa (o se suscribe a él) en algún lugar fuera de la vida útil de la vista, acaba de filtrar toda su actividad.
Por lo tanto, si acaba de suscribirse dentro de su ViewHolder no hay necesidad de darse de baja como si no hubiera necesidad de anular el registro de un oyente de clics si lo hacía manualmente.
Sí, si miras en el doc , dice explícitamente:
- Advertencia: El observable creado mantiene una referencia fuerte a la
view
. Anular la suscripción para liberar esta referencia.
Sí, debe darse de baja al utilizar RxBinding .
Aquí hay una forma … (en java, podría ser modificado para kotlin?)
Recoger
Dentro de su Actividad o Fragmento, agregue desechables a un CompositeDisposable que dispondrá en onDestroy ().
CompositeDisposable mCompD; // collector Disposable d = RxView.clicks(mButton).subscribe(new Consumer...); addToDisposables(mCompD, d); // add to collector public static void addToDisposables(CompositeDisposable compDisp, Disposable d) { if (compDisp == null) { compDisp = new CompositeDisposable(); } compDisp.add(d); }
Disponer
@Override protected void onDestroy() { mCompD.dispose(); super.onDestroy(); }
- Cómo deshabilitar la animación de etiqueta flotante al rellenar los campos EditText envueltos en TextInputLayout
- ¿Es posible tener el último elemento en un RecyclerView para ser acoplado a la parte inferior si no hay necesidad de desplazarse?