2016-02-12 4 views
1

Auparavant, j'utilisais un Runnable avec un Handler, et j'exécutais .postDelayed(runnable, delay) avec un délai de 3 secondes, pour envoyer une requête réseau à une API, pour mettre à jour les coordonnées sur une carte. J'ai pensé que c'était une grande opportunité d'essayer d'obtenir un Rx. J'ai changé l'appel Retrofit pour retourner un Observable, et utiliser l'opérateur .interval() pour implémenter les appels répétés. Voici mon code actuel:Exécuter une requête réseau toutes les X secondes, comment faire une pause/reprendre?

Observable.interval(3000, TimeUnit.MILLISECONDS) 
      .flatMap(new Func1<Long, Observable<IssResponse>>() { 
       @Override 
       public Observable<IssResponse> call(Long aLong) { 
        Log.d("api", "inside the call method: " + aLong.toString()); 
        return issService.getLocation(); 
       } 
      }).subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<IssResponse>() { 
       @Override 
       public void onCompleted() { 
        Log.d("api", "rx comleted"); 
       } 

       @Override 
       public void onError(Throwable e) { 
       } 

       @Override 
       public void onNext(IssResponse issResponse) { 
        Log.d("api", "response: " + issResponse.getIssPosition().getLatitude().toString()); 
       } 
      }); 

Cela semble fonctionner comme prévu, et renvoie un résultat toutes les 3 secondes. Maintenant, ce que je voudrais faire, c'est "pause" et ensuite reprendre ces demandes, comme avec le cycle de vie Android, je ne veux pas continuer à exécuter des demandes si l'utilisateur passe à un fragment différent afin que la carte n'est même pas visible.

Avec le Handler et Runnable, je pensais que je pourrais appeler handler.removeCallbacks(runnable) dans la méthode onPause(), qui semblait fonctionner bien pour les demandes faisant une pause. Je n'ai pas réussi à mettre en œuvre la fonctionnalité de reprise en utilisant la méthode Handler et Runnable comme j'ai décidé de passer à Rx. Alors, comment cette fonctionnalité pourrait-elle être implémentée avec Rx? Comment puis-je faire une pause et reprendre plus tard les demandes en utilisant RxJava?

EDIT: trouvé un moyen de mettre en pause en utilisant Observable.takeWhile(boolean) et en basculant le booléen. Maintenant, j'ai juste besoin d'un moyen de reprendre ..

Répondre

3

Comme votre Observable n'est pas hot Je vous suggère une méthode alternative et plus simple: il suffit de vous abonner et de vous désabonner de votre Observable.

Créez votre Observable intérieur onCreate de votre fragment/activity/presenter et enregistrer référence:

private Observable<IssResponse> observable; 
observable = Observable 
     .interval(3000, TimeUnit.MILLISECONDS) 
     .flatMap(new Func1<Long, Observable<IssResponse>>() { 
      //... 
     }); 

En onResume abonnez-vous et enregistrer référence à Subscription:

private Subscription subscription; 
subscription = observable.subscribe(result -> { 
    //user your data 
}); 

Et enfin désabonnement dans /onStop :

subscription.unsubscribe(); 

Aussi il ya RxLifecycle bibliothèque, je ne l'utilise pas donc je ne suis pas sûr que cela corresponde à votre exigence avec interval.

+0

C'est à peu près ce que j'ai fini par faire. J'utilise actuellement un MapFragment Google, donc j'ai un callback 'onMapReady()', où j'ai une méthode d'assistance qui s'abonne à Retrofit Observable et commence à interroger l'API. Je bascule alors une valeur booléenne dans 'onPause()' pour arrêter l'Observable en utilisant '.takeWhile()'. Ensuite, dans 'onResume() ', je bascule la valeur booléenne et duplique le même code Observable que précédemment. Cela semble fonctionner, mais je n'aime vraiment pas ce code de duplication im. J'espère que quelqu'un sait d'une meilleure façon. – Orbit