Android.view.ViewRootImpl$CalledFromWrongThreadException: Только исходный поток, создавший иерархию представлений, может касаться своих представлений. (RxJava)

Я нашел много статей об ошибке, которую я получаю, я знаю, что мы можем обновлять пользовательский интерфейс только из основного потока. Позвольте мне рассказать вам всю ошибку, которую я получаю:

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 не обновляет его в пользовательском интерфейсе.

И позвольте мне рассказать вам о самой сложной части: если я переведу приложение на передний план, заблокировав экран или нажав кнопку «Домой», и вернусь в приложение, мой пользовательский интерфейс обновится с данными, которые я получил.

0
0
241
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны использовать observeOn(AndroidSchedulers.mainThread()), а не subscribeOn(AndroidSchedulers.mainThread()). Использовать как

.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())

subscribeOn используется для указания планировщика, на котором будет работать Observable. В вашем случае это будет планировщик ввода-вывода.

ObserveOn используется указать Scheduler, на котором наблюдатель будет наблюдать за этим Observable, т.е. завершением в данном случае будет Main thread

омг ... как я могу сделать глупую ошибку ... я знаю основы ... но, поскольку я новичок, я сделал это ... спасибо ...

sum20156 24.12.2020 08:32

Другие вопросы по теме