您好我刚开始使用RxJava2学习反应式编程。 如何创建在后台线程中运行的任务,然后使用RxJava2在主线程上完成。
Android中的示例我们使用AsyncTask就像下面的示例
private class MyTask extends AsyncTask<String, Integer, Boolean>
{
@Override
protected Boolean doInBackground(String... paths)
{
for (int index = 0; index < paths.length; index++)
{
boolean result = copyFileToExternal(paths[index]);
if (result == true)
{
// update UI
publishProgress(index);
}
else
{
// stop the background process
return false;
}
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
int count = values[0];
// this will update my textview to show the number of files copied
myTextView.setText("Total files: " + count);
}
@Override
protected void onPostExecute(Boolean result)
{
super.onPostExecute(result);
if (result)
{
// display a success dialog
ShowSuccessAlertDialog();
}
else
{
// display a fail dialog
ShowFailAlertDialog();
}
}
}
对于这个例子,我想传入一个Strings的Array / ArrayList,它用于在 后台线程 中执行一些方法。然后,每个成功结果都将更新我的 TextView(UI线程)。如果其中一个进程失败,我希望它直接停止。最后,我想在流程完成后更新我的视图。
我只能设法做到这一点
Observable.just(paths).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ArrayList<String>>()
{
private boolean result;
@Override
public void onSubscribe(Disposable d)
{
}
@Override
public void onNext(ArrayList<String> paths)
{
for (int index = 0; index < paths.size(); index++)
{
result = copyFileToExternal(paths[index]);
if (result == true)
{
// cant update UI because is in background thread
myTextView.setText("Total files: " + index);
}
else
{
// end the loop
break;
}
}
}
@Override
public void onError(Throwable e)
{
}
@Override
public void onComplete()
{
if (result)
{
// cant display because it is still in background thread
ShowSuccessAlertDialog();
}
else
{
// cant display because it is still in background thread
ShowFailAlertDialog();
}
}
});
我查看了一些教程,但似乎无法找到答案。
提前感谢您的帮助
答案 0 :(得分:4)
我会做这样的事情:
Observable.fromArray(getPaths())
.map(path -> copyFileToExternal(path))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aInteger -> Log.i("test", "update UI"),
throwable -> ShowFailAlertDialog),
() -> ShowSuccessAlertDialog());
一个好主意通常是拥有一个&#34;处理程序&#34;用于控制对观察者的订阅。因此,当您需要停止后台任务时(例如,因为用户离开了Activity),您可以使用它。为此,您可以使用subscribeWith
而不是subscribe
作为输入ResourceObserver
:这样您就可以得到Disposable
。
Disposable subscription = Observable.fromArray(getPaths())
.map(path -> copyFileToExternal(path))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new ResourceObserver<Integer>() {
@Override
public void onNext(@NonNull Integer index) {
Log.i("test", "update UI");
}
@Override
public void onError(@NonNull Throwable e) {
ShowFailAlertDialog();
}
@Override
public void onComplete() {
ShowSuccessAlertDialog();
}
});
当您需要停止任务时,您可以致电:
subscription.dispose();
答案 1 :(得分:1)
我是新手,但我有一个有效的例子......
//Observable
Observable.just("input_parameter")
.subscribeOn(Schedulers.io())//creation of secondary thread
.map(new Function<String, String>() {//<input obj,return obj>
@Override
public String apply(String cad){//input obj
Log.d(TAG,"thread :"+Thread.currentThread().getName());
//runs in a secondary thread
return "result text: "+doLongNetworkOperation();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(MyObserver);//now this runs in main thread
和MyObserver:
//Observer
Observer MyObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG,"onSubscribe thread:"+Thread.currentThread().getName());
}
@Override
public void onNext(Object value) {
Log.d(TAG,"on next, valor:<<"+value.toString()+">> \n nombre hilo:"+Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
Log.d(TAG,"error "+e.toString());
}
@Override
public void onComplete() {
Log.d(TAG,"onCompleted thread:"+Thread.currentThread().getName());
}
};
请告诉我这是否适合您。