No vuelva a ejecutar la llamada de Retrofit si todavía está en curso con RxJava 2

Mi objetivo es un método que ejecutará una llamada de red a menos que la llamada de red ya esté en curso, en cuyo caso la persona que llama se suscribe a los resultados de la llamada existente.

Esto es lo que tengo, en su mayoría funciona:

private AsyncSubject<Stuff> asyncSubject; public Observable<Stuff> getStuff() { if (asyncSubject == null) { asyncSubject = AsyncSubject.create(); asyncSubject .doAfterTerminate(new Action() { @Override public void run() throws Exception { asyncSubject = null; } }) .subscribe(); retrofitApi.getStuff() .subscribe(asyncSubject); } return asyncSubject .someOperatorsHere(); } 

Esto funciona principalmente porque asyncSubject se anula en terminate de modo que las llamadas subsiguientes volverán a ejecutar la solicitud de red.

Pero hay un error, hay una ventana entre if (asyncSubject == null) y return asyncSubject donde doAfterTerminate puede ejecutar y obtengo un puntero nulo.

Cualquier idea de cómo solucionar el error. Tal vez hay una manera más elegante Rx para hacer esto? O bloque synchronized . O una forma de consultar Retrofit para el progreso de la red.

Esta solución comparte la suscripción entre los suscriptores en curso.

 private Observable<Stuff> stuff = retrofitApi.getStuff().share(); public Observable<Stuff> getStuff() { return stuff .someOperatorsHere(); } 

Hay un par de posibles soluciones, sólo voy a describir el que es probablemente más simple en su caso.

Tienes 2 problemas: condición de raza, y anulación y recreación del tema, lo que es bastante inseguro.

Lo que puede hacer es guardar su Subscription aquí

 retrofitApi.getStuff().subscribe(asyncSubject); 

Y en lugar de comprobar if (asyncSubject == null) , puede comprobar if (s.isUnsubscribed()) .

Así que su código se verá más o menos así:

 private AsyncSubject<Stuff> asyncSubject = AsyncSubject.create(); private Subscription subscription = Subscriptions.unsubscribed(); public Observable<Stuff> getStuff() { if (subscription.isUnsubscribed()) { subscription = retrofitApi.getStuff() .subscribe(asyncSubject); } return asyncSubject .someOperatorsHere(); } 
  • RxJava: Cómo convertir Lista de objetos en Lista de otros objetos
  • La llamada onNext de PublishSubject en un hilo diferente después de actualizar a Retrofit 2.0
  • ¿Cómo utilizar Flowable en RxJava 2?
  • RxJava: Se produjo un error al intentar propagar el error a Observer.onError
  • Combinación de escuchas de datos en tiempo real Firebase con RxJava
  • Manejar errores en Retrofit 2 RX
  • Creando Observable sin utilizar Observable.create
  • Realm + Retrofit + Rxjava
  • Cómo limpiar RxJava fuego y olvidar suscripciones?
  • RxJava y Retrofit - Aumento de excepciones personalizadas en función de la respuesta del servidor
  • RxJava con presentador y fragmento retenido para cambios de configuración
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.