El resultado de subscribe no se utiliza


He actualizado a Android Studio 3.1 hoy, que parece haber añadido un par de comprobaciones más pelusa. Una de estas comprobaciones de pelusa es para llamadas RxJava2 subscribe() de una sola vez que no se almacenan en una variable. Por ejemplo, obtener una lista de todos los jugadores de la base de datos de mi habitación:

Single.just(db)
            .subscribeOn(Schedulers.io())
            .subscribe(db -> db.playerDao().getAll());

Resulta en un gran bloque amarillo y esta descripción:

El resultado de subscribe no se usa

introduzca la descripción de la imagen aquí

¿Cuál es la mejor práctica para llamadas Rx one-shot como esta? Debería mantener el control de la Disposable y dispose() en completa? ¿O debería simplemente @SuppressLint y seguir adelante?

EDITAR Esto solo parece afectar a RxJava2 (io.reactivex), RxJava (rx) no tiene esta pelusa.

Author: Michael Dodd, 2018-03-28

4 answers

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, su Single puede contener una llamada de red, que podría causar una pérdida de memoria si su Activity se abandona durante su ejecución.

Una forma conveniente de administrar una gran cantidad de Disposable s es usar una CompositeDisposable ; simplemente cree una nueva variable de instancia CompositeDisposable en su clase de inclusión, luego agregue todos sus Desechables a la CompositeDisposable (con RxKotlin puedes añadir addTo(compositeDisposable) a todos tus Desechables). Finalmente, cuando haya terminado con su instancia, llame a compositeDisposable.dispose().

Esto eliminará las advertencias de pelusa y asegurará que su Disposables se administre correctamente.

En este caso, el código se vería como:

CompositeDisposable compositeDisposable = new CompositeDisposable();

Disposable disposable = Single.just(db)
        .subscribeOn(Schedulers.io())
        .subscribe(db -> db.get(1)));

compositeDisposable.add(disposable); //IDE is satisfied that the Disposable is being managed. 
disposable.addTo(compositeDisposable); //Alternatively, use this RxKotlin extension function.


compositeDisposable.dispose(); //Placed wherever we'd like to dispose our Disposables (i.e. in onDestroy()).
 47
Author: urgentx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-08 21:59:46

En el momento en que la Actividad se destruya, la lista de Desechables se borra y estamos bien.

io.reactivex.disposables.CompositeDisposable mDisposable;

    mDisposable = new CompositeDisposable();

    mDisposable.add(
            Single.just(db)
                    .subscribeOn(Schedulers.io())
                    .subscribe(db -> db.get(1)));

    mDisposable.dispose(); // dispose wherever is required
 13
Author: Aks4125,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 04:07:59

Como se sugirió, puede usar un CompositeDisposable global para agregar el resultado de la operación subscribe allí.

La biblioteca RxJava2Extensions contiene métodos útiles para eliminar automáticamente el desechable creado de CompositeDisposable cuando se complete. Ver SubscribeAutoRelease sección, pero tenga en cuenta que hay un error en el método de nombrar allí subscribeAutoRelease en lugar de subscribeAutoDispose.

En su caso puede verse así

SingleConsumers.subscribeAutoDispose(
    Single.just(db)
            .subscribeOn(Schedulers.io()),
    composite,
    db -> db.playerDao().getAll())
 3
Author: httpdispatch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 07:03:47

Si estás seguro de que disposable se manejó correctamente, por ejemplo usando el operador doOnSubscribe (), puedes agregar esto a Gradle:

android {
lintOptions {
     disable 'CheckResult'
}}
 -1
Author: Ivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-02 12:32:07