Я нашел много статей об ошибке, которую я получаю, я знаю, что мы можем обновлять пользовательский интерфейс только из основного потока. Позвольте мне рассказать вам всю ошибку, которую я получаю:
E/RxEroor: The exception could not be delivered to the consumer because it has already cancelled/disposed of the flow or the exception has nowhere to go, to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Я получаю сообщение об ошибке, используя это:
RxJavaPlugins.setErrorHandler(throwable -> {
Log.e("RxEroor",throwable.getLocalizedMessage());
});
Я использую rxjava для наблюдения за вещами из модифицированного сетевого вызова. Вот мой вызов ViewModel из фрагмента для получения данных.
compositeDisposable.add(songsOfCategoryViewModel.getAllSongs(1)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<ServerResponse<JsonObject>>() {
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull ServerResponse<JsonObject> jsonObjectServerResponse) {
if (jsonObjectServerResponse.isStatus()){
Log.i("Songs Of Category",jsonObjectServerResponse.getData().toString());
List<SongModel> serverSongList = new Gson()
.fromJson(jsonObjectServerResponse.getData().get("songs")
.getAsJsonArray(),new TypeToken<List<SongModel>>(){}.getType());
localSongList.addAll(serverSongList);
songAdapter.notifyDataSetChanged();
/* Observable
.fromIterable(serverSongList)
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<SongModel>() {
@Override
public void onNext(@io.reactivex.rxjava3.annotations.NonNull SongModel songModel) {
Log.i("Song",songModel.getTitle());
localSongList.add(songModel);
songAdapter.notifyDataSetChanged();
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
}
@Override
public void onComplete() {
Log.i("onComplete","Called");
}
});
*/
}else {
Log.e("Error",jsonObjectServerResponse.getMessage());
}
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Log.e("Error",e.getMessage());
}
}));
Как видите, я предоставил AndroidSchedulers.mainThread() для подписки. Я получаю данные по методу onSucces, но адаптер recyclerview не обновляет его в пользовательском интерфейсе.
И позвольте мне рассказать вам о самой сложной части: если я переведу приложение на передний план, заблокировав экран или нажав кнопку «Домой», и вернусь в приложение, мой пользовательский интерфейс обновится с данными, которые я получил.
Вы должны использовать observeOn(AndroidSchedulers.mainThread()), а не subscribeOn(AndroidSchedulers.mainThread()). Использовать как
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
subscribeOn используется для указания планировщика, на котором будет работать Observable. В вашем случае это будет планировщик ввода-вывода.
ObserveOn используется указать Scheduler, на котором наблюдатель будет наблюдать за этим Observable, т.е. завершением в данном случае будет Main thread
омг ... как я могу сделать глупую ошибку ... я знаю основы ... но, поскольку я новичок, я сделал это ... спасибо ...