Actualicé a Android Studio 3.1 hoy, que parece haber agregado algunas comprobaciones de pelusas más. Una de estas comprobaciones de pelusa es para subscribe()
llamadas RxJava2 de una sola vez que no están almacenadas en una variable. Por ejemplo, obtener una lista de todos los jugadores de la base de datos de mi sala:
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.playerDao().getAll());
Resultados en un gran bloque amarillo y esta información sobre herramientas:
El resultado de
subscribe
no se utiliza
¿Cuál es la mejor práctica para llamadas Rx one-shot como esta? ¿Debo mantener el Disposable
y dispose()
en completa? ¿O debería simplemente @SuppressLint
seguir adelante?
Esto solo parece afectar a RxJava2 ( io.reactivex
), RxJava ( rx
) no tiene esta pelusa.
android
android-studio
rx-java2
lint
android-studio-3.1
Michael Dodd
fuente
fuente
Disposable
alcance de los miembros y llamodispose()
cuando se completa el single, pero parece innecesariamente engorroso. Estoy interesado en ver si hay mejores formas de hacerlo.Respuestas:
El IDE no sabe qué efectos potenciales puede tener su suscripción cuando no se elimina, por lo que la trata como potencialmente insegura. Por ejemplo,
Single
puede contener una llamada de red, lo que podría causar una pérdida de memoria siActivity
se abandona durante su ejecución.Una manera conveniente de administrar una gran cantidad de
Disposable
s es usar un CompositeDisposable ; simplemente cree una nuevaCompositeDisposable
variable de instancia en su clase adjunta, luego agregue todos sus Desechables a CompositeDisposable (con RxKotlin puede agregaraddTo(compositeDisposable)
a todos sus Desechables). Finalmente, cuando haya terminado con su instancia, llamecompositeDisposable.dispose()
.Esto eliminará las advertencias de pelusa y garantizará que
Disposables
se administren correctamente.En este caso, el código se vería así:
fuente
error: cannot find symbol method addTo(CompositeDisposable)
con "rxjava: 2.1.13". ¿De dónde viene este método? (RxSwift o RxKotlin, supongo)En el momento en que se destruya la Actividad, la lista de Desechables se borra y estamos bien.
fuente
Puede suscribirse con DisposableSingleObserver :
En caso de que necesite disponer directamente del
Single
objeto (por ejemplo, antes de que se emita), puede implementar un métodoonSubscribe(Disposable d)
para obtener y usar laDisposable
referencia.También puede realizar la
SingleObserver
interfaz por su cuenta o utilizar otras clases secundarias.fuente
Como se sugirió, puede usar algo global
CompositeDisposable
para agregar el resultado de la operación de suscripción allí.La biblioteca RxJava2Extensions contiene métodos útiles para eliminar automáticamente los elementos desechables creados
CompositeDisposable
cuando se completa. Consulte la sección subscribeAutoDispose .En su caso, puede verse así
fuente
Puede usar Uber AutoDispose y rxjava
.as
Asegúrese de comprender cuando se da de baja en base a ScopeProvider.
fuente
Una y otra vez me encuentro volviendo a la cuestión de cómo deshacerme correctamente de las suscripciones, y a esta publicación en particular. Varios blogs y charlas afirman que no llamar
dispose
necesariamente conduce a una pérdida de memoria, lo cual creo que es una declaración demasiado general. Según tengo entendido, la advertencia de pelusa sobre no almacenar el resultadosubscribe
no es un problema en algunos casos, porque:Como no quiero suprimir las advertencias de pelusas, recientemente comencé a usar el siguiente patrón para casos con un observable sincrónico:
Me interesaría cualquier comentario sobre esto, independientemente de si se trata de una confirmación de corrección o el descubrimiento de una escapatoria.
fuente
Hay otra forma disponible, que es evitar el uso de Desechables manualmente (agregar y eliminar suscripciones).
Puede definir un Observable y ese observable recibirá el contenido de un SubjectBehaviour (en caso de que use RxJava). Y al pasar eso observable a su LiveData , eso debería funcionar. Mira el siguiente ejemplo basado en la pregunta inicial:
fuente
Si está seguro de que el desechable se manejó correctamente, por ejemplo, utilizando el operador doOnSubscribe (), puede agregar esto a Gradle:
fuente
@SuppressLint("CheckResult")
solo el método.