1

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?

Tom
  • 21
  • 4
  • Possible duplicate of [How do I fix android.os.NetworkOnMainThreadException?](https://stackoverflow.com/questions/6343166/how-do-i-fix-android-os-networkonmainthreadexception) – AskNilesh Apr 11 '18 at 09:30
  • Because you cannot perform network options in its main thread. Use Threads or async task to perform network operations. But take care if any ui elements are there then it should be done on main or ui thread. – Amit Jangid Apr 11 '18 at 09:32
  • https://stackoverflow.com/questions/27687907/android-os-networkonmainthreadexception-using-rxjava-on-android – AskNilesh Apr 11 '18 at 09:32
  • Why are you subscribing twice? You have a `subscribe()` and then another `subscribe(new Observer...)`. – akarnokd Apr 11 '18 at 09:33
  • @AmitJangid but i am nor performing network operation on main thread – Tom Apr 11 '18 at 09:34
  • @NileshRathod Already seen that link..this one related to rxjava – Tom Apr 11 '18 at 09:34

2 Answers2

1

You are subscribing twice, the second time to the unmodified call source. You should have something like this:

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

    }
});
akarnokd
  • 69,132
  • 14
  • 157
  • 192
1

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

            }
        });
Dmitry
  • 2,326
  • 1
  • 13
  • 18