简体   繁体   English

RxJava2就像Android中的AsyncTask一样

[英]RxJava2 that acts like AsyncTask in Android

Hi I just start learning Reactive programming using RxJava2. 嗨,我刚开始学习使用RxJava2进行反应式编程。 How do I create a task that runs in the background thread and then complete on main thread using RxJava2. 如何创建在后台线程中运行的任务,然后使用RxJava2在主线程上完成。

Example in Android we use AsyncTask just like example below 在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();
        }
    }
}

For this example I want to pass in a Array / ArrayList of Strings and it is use to execute some method in the background thread . 对于这个例子,我想传入一个字符串的Array / ArrayList,它用于在后台线程中执行一些方法。 Then every success result will update my TextView (UI thread) . 然后每个成功结果都将更新我的TextView(UI线程) If one of the process fail, I want it to stop directly. 如果其中一个进程失败,我希望它直接停止。 Lastly I want to update my Views when the process has completed. 最后,我想在流程完成后更新我的视图

I only manage to get this far 我只能做到这一点

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();
                    }
                }
            });

I looked at a few tutorials but can't seem to find the answer. 我看了几个教程,但似乎无法找到答案。

Thanks in advance for the help 在此先感谢您的帮助

I would do something like this: 我会做这样的事情:

Observable.fromArray(getPaths())
    .map(path -> copyFileToExternal(path))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(aInteger -> Log.i("test", "update UI"),
               throwable -> ShowFailAlertDialog),
               () -> ShowSuccessAlertDialog());

A good idea is usually to have a "handler" for controlling the subscription to your observer. 一个好主意通常是拥有一个“处理程序”来控制对观察者的订阅。 So that, when you need to stop your background task (for example because the user left the Activity), you can use it. 因此,当您需要停止后台任务时(例如,因为用户离开了Activity),您可以使用它。 For this purpose you can use subscribeWith instead of subscribe , that receive as input a ResourceObserver : in this way you get a Disposable . 为此,您可以使用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();
         }
   });

When you need to stop the task you can just call: 当您需要停止任务时,您可以致电:

subscription.dispose();

I'm new at this, but I got a working example.. 我是新手,但我有一个有效的例子..

//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

And MyObserver: 和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());
    }
};

Plz, let me know if this works for you. Plz,请告诉我这是否适合你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM