如何在onError调用后继续订阅observable

时间:2017-08-21 06:08:33

标签: android retrofit2 rx-android rx-java2

我是 RxJava 的新手,我通过一些示例来学习。我已经做了一个示例RxJava Retrofit 应用程序,它将显示来自http://www.omdbapi.com的电影的详细信息。该应用程序有一个searchBox用户输入一个电影名称,该名称将被提取并作为api请求发送,并在响应时显示结果。我的问题是每当发生错误时,在 onError 之后,edittext observable不再发出任何内容。因此,基本上如果一个电影搜索由于任何API错误而失败,我需要关闭并重新启动应用程序以继续进行电影搜索。即使在onError之后,我如何观察编辑文本更改?以下是我的代码:

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {

private static final String TAG = "LOG";
@Inject
ApiInterface mApiInterface;
private MainActivityViewHelper mMainActivityViewHelper;
BehaviorSubject<String> mStringSubject = BehaviorSubject.create();
private ViewModel mVm;
private Observer<MovieData> mMovieDataObserver;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //setting up views / databining and dagger
    mVm = new ViewModel();
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setVm(mVm);
    App.get(this).getAppComponent().inject(this);
    mMainActivityViewHelper = new MainActivityViewHelper();
    mMainActivityViewHelper.setSearchToolbar(this, this);


    searchSubscription().subscribe(mMovieDataObserver);


}

private Observable<MovieData> searchSubscription() {
    mMovieDataObserver = new Observer<MovieData>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
            Log.d(TAG, "onSubscribe: ");
        }

        @Override
        public void onNext(@NonNull MovieData movieData) {
            Log.d(TAG, "onNext: " + movieData);
            mVm.loading.set(false);
            mVm.moviedata.set(movieData);
        }

        @Override
        public void onError(@NonNull Throwable e) {
            Log.d(TAG, "onError: " + e.getMessage());
            searchSubscription();
        }

        @Override
        public void onComplete() {
            Log.d(TAG, "onComplete: ");
        }
    };

    Observable<MovieData> movieDataObservable = mStringSubject
            .filter(s -> s != null)
            .doOnNext(s -> Log.d(TAG, s))
            .debounce(500, TimeUnit.MILLISECONDS)
            .doOnNext(s -> Log.d(TAG, "onCreate: " + s))
            .flatMap(s -> mApiInterface.getMovie(s))
            .onErrorReturn(throwable -> null)
            .doOnSubscribe(disposable -> mVm.loading.set(true))
            .doFinally(() -> mVm.loading.set(false))
            .subscribeOn(Schedulers.computation())
            .observeOn(AndroidSchedulers.mainThread());

    return movieDataObservable;
}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    getMenuInflater().inflate(R.menu.menu_home, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                Anim.circleReveal(this, R.id.searchtoolbar, 1, true, true);
            else
                mMainActivityViewHelper.mSearchToolbar.setVisibility(View.VISIBLE);
            mMainActivityViewHelper.mItem.expandActionView();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

@Override
public boolean onQueryTextSubmit(String query) {
    return true;
}

@Override
public boolean onQueryTextChange(String newText) {
    mStringSubject.onNext(newText);
    return true;
  }


}

1 个答案:

答案 0 :(得分:1)

此处,当改装observable中发生错误时,错误将继续显示在您的主要observable中,然后您的流停止。您可以跳过改装observable中的错误以传递到主流。你可以使用任何 错误处理此处指定的运算符How to ignore error and continue infinite stream?

尝试将一些错误处理应用于您从flatMap

返回的改装observable

例如

Observable<MovieData> movieDataObservable = mStringSubject
        .filter(s -> s != null)
        .doOnNext(s -> Log.d(TAG, s))
        .debounce(500, TimeUnit.MILLISECONDS)
        .doOnNext(s -> Log.d(TAG, "onCreate: " + s))
        .flatMap(s -> mApiInterface.getMovie(s).onErrorReturn(throwable -> new MovieData()))
        .doOnSubscribe(disposable -> mVm.loading.set(true))
        .doFinally(() -> mVm.loading.set(false))
        .subscribeOn(Schedulers.computation())
        .observeOn(AndroidSchedulers.mainThread());

此处,出现错误时,改装observable将返回一个空的MovieData对象,而不是调用onError。您可以检查错误案例的空MovieData对象并相应处理