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

时间:2015-10-31 00:17:23

标签: android rx-java

I have an observable that does some IO processing on the background thread: 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); } } } After the io work is done, I want to hide the progressBar. Of course I cannot do this inside call(Subscriber) of my anonymous class because accessing ui elements from the io thread will throw an exception.

1 个答案:

答案 0 :(得分:3)

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

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,因为初学者背压。