我是 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;
}
}
答案 0 :(得分:1)
此处,当改装observable中发生错误时,错误将继续显示在您的主要observable中,然后您的流停止。您可以跳过改装observable中的错误以传递到主流。你可以使用任何 错误处理此处指定的运算符How to ignore error and continue infinite stream?
尝试将一些错误处理应用于您从flatMap
例如
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
对象并相应处理