Search code examples
androidrx-javaretrofit2rx-java2networkonmainthread

NetworkOnMainThreadException with .subscribeOn(Schedulers.newThread())


I am trying to fetch list from an api and display in recyclerview using Retrofit with RxJava.

I have used below code-

    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();

        }
    });

Below two lines specify that the REST call will be made in a new thread . And when the call response returns, the onNext, onError, and onComplete methods are called on the mainThread.

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

But I am getting NetworkOnMainThreadException which is thrown when an application attempts to perform a networking operation on its main thread.Why am i getting this exception and how can i resolve this?


Solution

  • That's because you are subscribing to the observable 2 times. You can remove subscribe method from here:

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

    So it will look like this:

    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();
    
                }
            });