I want to use a progress bar with RxJava like you can with AsyncTask
10,611
Solution 1
- In RxJava you have the do operators, that creates
Observable
lifecycle events listeners, in your case you want to do something (update the UI) before the task started, which mean you want thedoOnSubscribe
event. (side note it is true with 'cold' Observables that started thier work when subscrbied to - like your case) Just beware to call.observeOn(AndroidSchedulers.mainThread()))
before thedoOnSubscribe
in order to get notified on the mainThread, as you're updating the UI. -
Instead of using both
defer
andjust
return Observable.defer(new Func0<Observable<Void>>() { @Override public Observable<Void> call() { return Observable.just(myTask()); } });
you can use
fromCallable
:Observable.fromCallable(new Callable<Object>() { @Override public Object call() throws Exception { return myTask(); } })
Solution 2
Here is how I would do it:
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
})
Solution 3
I am showing progressBar
indoOnSubscribe()
, hiding in doOnError()
and in subscribe()
.
Please refer to this link for more details.
Related videos on Youtube
Author by
Kristy Welsh
Updated on September 15, 2022Comments
-
Kristy Welsh over 1 year
I want to replace my AsyncTask with RxJava in android. My current AsyncTask goes like this:
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(); } }
Here's my RxJava replacement:
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; }
My Activity:
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()); } }
How do I mimic the onPreExecute() method in the AsyncTask where I kick off the progressDialog?