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?
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();
}
})
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
})
Je montre progressBar
indoOnSubscribe()
, me cachant dans doOnError()
et dans subscribe()
.
Veuillez vous référer à this link pour plus de détails.
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 .