带有.subscribeOn的NetworkOnMainThreadException(Schedulers.newThread())

时间:2018-04-11 09:30:27

标签: android rx-java retrofit2 rx-java2 networkonmainthread

我正在尝试从api中获取列表,并使用Retrofit和RxJava在recyclerview中显示。

我使用了以下代码 -

    ApiInterface apiService =
            ApiService.getClient().create(ApiInterface.class);

    Observable<MoviesResponse> call = apiService.getTopRatedMovies(API_KEY);
    call.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe();
    call.subscribe(new Observer<MoviesResponse>() {
        @Override
        public void onSubscribe(Disposable d) {
            Toast.makeText(getApplicationContext(), d.toString(), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onNext(MoviesResponse moviesResponse) {
            movies=moviesResponse;
            moviesAdapter.notifyDataSetChanged();
        }

        @Override
        public void onError(Throwable e) {
            Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onComplete() {
            Toast.makeText(getApplicationContext(), "complete", Toast.LENGTH_LONG).show();

        }
    });

以下两行指定将在新线程中进行REST调用。当调用响应返回时,在mainThread上调用onNext,onError和onComplete方法。

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

但是我得到 NetworkOnMainThreadException ,当应用程序尝试在其主线程上执行网络操作时会抛出它。为什么我会收到此异常以及如何解决此问题?

2 个答案:

答案 0 :(得分:1)

您正在订阅两次,第二次订阅未修改的呼叫源。你应该有这样的东西:

ApiInterface apiService =
        ApiService.getClient().create(ApiInterface.class);

Observable<MoviesResponse> call = apiService.getTopRatedMovies(API_KEY);

call.subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<MoviesResponse>() {
    @Override
    public void onSubscribe(Disposable d) {
        Toast.makeText(getApplicationContext(), d.toString(), Toast.LENGTH_LONG).show();

    }

    @Override
    public void onNext(MoviesResponse moviesResponse) {
        movies=moviesResponse;
        moviesAdapter.notifyDataSetChanged();
    }

    @Override
    public void onError(Throwable e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();

    }

    @Override
    public void onComplete() {
        Toast.makeText(getApplicationContext(), "complete", Toast.LENGTH_LONG).show();

    }
});

答案 1 :(得分:1)

那是因为你订阅了2次观察。您可以从此处删除订阅方法:

call.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe();

所以它看起来像这样:

ApiInterface apiService =
            ApiService.getClient().create(ApiInterface.class);

   call.subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<MoviesResponse>() {
            @Override
            public void onSubscribe(Disposable d) {
                Toast.makeText(getApplicationContext(), d.toString(), Toast.LENGTH_LONG).show();

            }

            @Override
            public void onNext(MoviesResponse moviesResponse) {
                movies=moviesResponse;
                moviesAdapter.notifyDataSetChanged();
            }

            @Override
            public void onError(Throwable e) {
                Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();

            }

            @Override
            public void onComplete() {
                Toast.makeText(getApplicationContext(), "complete", Toast.LENGTH_LONG).show();

            }
        });