web-dev-qa-db-fra.com

Je veux utiliser une barre de progression avec RxJava comme vous pouvez avec AsyncTask

Je souhaite remplacer mon AsyncTask par RxJava sous Android. Mon AsyncTask actuelle va comme ceci: 

public class ProgressBarAsyncTask extends AsyncTask<Void,Void,Void> { 

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        ringProgressDialog = ProgressDialog.show(context,"MyProgressBarTitle","Working please wait",true, false);                  
    }

    @Override
    protected Void doInBackground(Void... void) { 
       //do work
       myTask();
       return null;
    }

    @Override
    protected void onPostExecute(Void void) {
        super.onPostExecute();
        ringProgressDialog.dismiss();
    }
}

Voici mon remplacement de RxJava:

    public static Observable<Void> getObservable(final Context context,final String... params) {

       return Observable.defer(new Func0<Observable<Void>>() {
          @Override
          public Observable<Void> call() {
             return Observable.just(myTask());
          }
       });

   }

    public static Subscriber<Void> getSubscriber() {
    Subscriber<Void> subscriber = new Subscriber<Void>() {
        @Override
        public void onCompleted() {
           ringProgressDialog.dismiss();

        }

        @Override
        public void onError(Throwable e) {
            Log.d(TAG,e.toString());

        }

        @Override
        public void onNext(Void aVoid) {
             manipulateData();

        }
    };
    return subscriber;
}

Mon activité:

public class MainActivity extends Activity { 
   private ProgressDialog ringProgressDialog;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      GetNumberObservable.Observable()
                       .subscribeOn(Schedulers.io())
                       .observeOn(AndroidSchedulers.mainThread()))
                       .subscribe(getSubscriber());
   }
}

Comment puis-je imiter la méthode onPreExecute () dans la AsyncTask où je lance le progressDialog? 

8
Kristy Welsh
  • Dans RxJava, vous avez les opérateurs do , qui créent des écouteurs Observable De cycle de vie, vous souhaitez faire quelque chose (Mettre à jour l'interface utilisateur) avant le début de la tâche. veut l'événement doOnSubscribe. (Remarque secondaire, c’est vrai avec les observables «froides» qui ont commencé à travailler après avoir souscrit - comme dans votre cas.] Prenez soin d’appeler .observeOn(AndroidSchedulers.mainThread())) avant la doOnSubscribe afin d’obtenir notifié sur le mainThread, car vous mettez à jour l'interface utilisateur.
  • Au lieu d'utiliser à la fois defer et just

    return Observable.defer(new Func0<Observable<Void>>() {
         @Override
         public Observable<Void> call() {
            return Observable.just(myTask());
         }
      });  
    

    vous pouvez utiliser fromCallable:

        Observable.fromCallable(new Callable<Object>() {
           @Override
           public Object call() throws Exception {
               return myTask();
           }
       })
    
3
yosriz

Voici comment je le ferais:

public final class ProgressOrResult<T> {
    final int progress;
    final T result;
    public ProgressOrResult(int progress, T result) {
        this.progress = progress;
        this.result = result;
    }
}

ProgressDialog ringProgressDialog = ProgressDialog.show(
    context, "MyProgressBarTitle", "Working please wait", true, false);                  


Observable.fromEmitter((Emitter<ProgressOrResult> emitter) -> {
    // generate "progress"
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
        emitter.onNext(new ProgressOrResult(i, null));
        Thread.sleep(1);
    }
    // generate "result"
    emitter.onNext(new ProgressOrResult(100, sum));
    emitter.onComplete();

}, BackpressureMode.BUFFER)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
    if (pr.result == null) {
        ringProgressDialog.setProgress(pr.progress);
    } else {
        ringProgressDialog.dismiss();        

        // process the result here
    }
}, error -> {
    // handle error here
})
3
akarnokd

Je montre progressBar indoOnSubscribe(), me cachant dans doOnError() et dans subscribe().

Veuillez vous référer à this link pour plus de détails.

1
Levon Petrosyan

Promotion sans vergogne

J'ai créé bibliothèque RxLoading pour cela, il peut faire ceci et bien plus encore,

vous pouvez simplement faire quelque chose comme ceci:

networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...);

il se compose de 2 classes, une vue personnalisée (loadingLayout) et RxLoading qui est un transformateur qui colle le tout ensemble, vous pouvez choisir de travailler avec les deux ou l’un d’eux. si vous voulez RxLoading avec une simple barre de progression, il vous suffit de mettre en place une interface et vous avez terminé.

vous pouvez en savoir plus sur la page GitHub .

0
ndori