我想在 RxJava 中使用进度条,就像在 AsyncTask 中一样
Posted
技术标签:
【中文标题】我想在 RxJava 中使用进度条,就像在 AsyncTask 中一样【英文标题】:I want to use a progress bar with RxJava like you can with AsyncTask 【发布时间】:2017-07-08 10:09:11 【问题描述】:我想在 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;
我的活动:
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() 方法?
【问题讨论】:
使用 doOnNext() 方法 @Tuby 你是怎么做到的? 查找这个类github.com/TwistedEquations/android-rxmvp-tutorial/blob/master/…,它使用doOnNext设置showLoading为true,开启进度条,你可以在这个方法中调用ringProgressDialog.show()。 【参考方案1】:我会这样做:
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
)
【讨论】:
【参考方案2】: 在 RxJava 中,您有 do 运算符,它创建Observable
生命周期事件监听器,在你的情况下你想做一些事情
(更新 UI)在任务开始之前,这意味着你想要
doOnSubscribe
事件。 (旁注对于“冷” Observables 是正确的
在订阅时开始他们的工作 - 就像你的情况一样)只是
请注意之前致电.observeOn(AndroidSchedulers.mainThread()))
doOnSubscribe
以便在主线程上得到通知,如
您正在更新用户界面。
而不是同时使用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();
)
【讨论】:
【参考方案3】:我在doOnSubscribe()
中显示progressBar
,隐藏在doOnError()
和subscribe()
中。
更多详情请参考this链接。
【讨论】:
【参考方案4】:无耻宣传
我为此创建了RxLoading library,它可以做到这一点以及更多,
你可以这样做:
networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...);
它由 2 个类组成,一个自定义视图 (loadingLayout) 和 RxLoading,它是一个 transformer,将它们粘合在一起,您可以选择使用两者或其中之一。 如果你希望 RxLoading 带有一个简单的进度条,你只需要实现一个接口就可以了。
您可以在GitHub page 上查看更多信息。
【讨论】:
以上是关于我想在 RxJava 中使用进度条,就像在 AsyncTask 中一样的主要内容,如果未能解决你的问题,请参考以下文章