在 RxJava 中后台线程完成后如何访问主线程?

How do I access the main thread after a background thread completes in RxJava?

我有一个在后台线程上进行一些 IO 处理的可观察对象:

progressBar.setVisibility(View.VISIBLE);
Observable.create(new OnSubscribe<File>() {

        @Override public void call(Subscriber<? super File> subscriber) {
            InputStream inputStream = null;
            FileOutputStream outputStream = null;

            try {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                    URL url = new URL(downloadUrl);
                    URLConnection conn = url.openConnection();
                    inputStream = conn.getInputStream();

                    File saveDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                    File downloadedFile = new File(saveDir, filename);
                    outputStream = new FileOutputStream(downloadedFile);
                    byte[] buffer = new byte[4096];
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                }
            }

io工作完成后,我想隐藏progressBar。当然,我不能在我的匿名 class 的 call(Subscriber) 中执行此操作,因为从 io 线程访问 ui 元素将引发异常。

我认为常见的模式是 .observeOn(AndroidSchedulers.mainThread())。为简洁起见使用 lambda:

progressBar.setVisibility(View.VISIBLE);
Observable.create(new OnSubscribe<File()...)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .doOnCompleted(() -> progressBar.setVisibility(invisible))
  .subscribe(file -> {}, error -> reportError(error));

如果您想在完成或出错时隐藏进度条,则可以将 .doOnCompleted 替换为 .doOnTerminate

一个快速警告,你应该尽最大努力避免 Observable.create 因为初学者的背压。