我想在 RxJava 中使用进度条,就像在 AsyncTask 中一样
I want to use a progress bar with RxJava like you can with AsyncTask
我想在 android 中用 RxJava 替换我的 AsyncTask。我当前的 AsyncTask 是这样的:
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();
}
}
这是我的 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;
}
我的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());
}
}
如何在启动 progressDialog 的 AsyncTask 中模仿 onPreExecute() 方法?
- 在 RxJava 中你有 do 运算符,它创建
Observable
生命周期事件监听器,在你的情况下你想做一些事情
(更新 UI) 在任务开始之前,这意味着你想要
doOnSubscribe
事件。 (附注 'cold' Observables 是正确的
在订阅时开始他们的工作 - 就像你的情况一样)只是
注意之前调用 .observeOn(AndroidSchedulers.mainThread()))
doOnSubscribe
以便在主线程上得到通知,因为
您正在更新 UI.
而不是同时使用 defer
和 just
return Observable.defer(new Func0<Observable<Void>>() {
@Override
public Observable<Void> call() {
return Observable.just(myTask());
}
});
你可以使用 fromCallable
:
Observable.fromCallable(new Callable<Object>() {
@Override
public Object call() throws Exception {
return myTask();
}
})
我会这样做:
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
})
无耻宣传
我为此创建了 RxLoading library,它可以做到这一点以及更多,
你可以这样做:
networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...);
它由 2 个 类、一个自定义视图 (loadingLayout) 和 transformer 将它们粘合在一起的 RxLoading 组成,您可以选择同时使用这两个视图或其中一个。
如果你想要 RxLoading 有一个简单的进度条,你只需要实现一个接口就可以了。
您可以在 GitHub page 上查看更多信息。
我在 doOnSubscribe()
中显示 progressBar
,在 doOnError()
和 subscribe()
中隐藏。
详情请参考thislink
我想在 android 中用 RxJava 替换我的 AsyncTask。我当前的 AsyncTask 是这样的:
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();
}
}
这是我的 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;
}
我的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());
}
}
如何在启动 progressDialog 的 AsyncTask 中模仿 onPreExecute() 方法?
- 在 RxJava 中你有 do 运算符,它创建
Observable
生命周期事件监听器,在你的情况下你想做一些事情 (更新 UI) 在任务开始之前,这意味着你想要doOnSubscribe
事件。 (附注 'cold' Observables 是正确的 在订阅时开始他们的工作 - 就像你的情况一样)只是 注意之前调用.observeOn(AndroidSchedulers.mainThread()))
doOnSubscribe
以便在主线程上得到通知,因为 您正在更新 UI. 而不是同时使用
defer
和just
return Observable.defer(new Func0<Observable<Void>>() { @Override public Observable<Void> call() { return Observable.just(myTask()); } });
你可以使用
fromCallable
:Observable.fromCallable(new Callable<Object>() { @Override public Object call() throws Exception { return myTask(); } })
我会这样做:
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
})
无耻宣传
我为此创建了 RxLoading library,它可以做到这一点以及更多,
你可以这样做:
networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...);
它由 2 个 类、一个自定义视图 (loadingLayout) 和 transformer 将它们粘合在一起的 RxLoading 组成,您可以选择同时使用这两个视图或其中一个。 如果你想要 RxLoading 有一个简单的进度条,你只需要实现一个接口就可以了。
您可以在 GitHub page 上查看更多信息。
我在 doOnSubscribe()
中显示 progressBar
,在 doOnError()
和 subscribe()
中隐藏。
详情请参考thislink