Search code examples
androidandroid-architecture-componentsandroid-livedataandroid-jetpackandroid-viewmodel

viewmodel making network call on screen orientation change android


I am new to android architecture components and I am little confused with viewmodel. I am building an app which get a list of items from the server and display as a list in the layout. I have implemented the network call in the Repository class.

Repository.java:

//Get list of top rated movies
    public LiveData<NetworkResponse> getTopRatedMovies() {
        final MutableLiveData<NetworkResponse> result = new MutableLiveData<>();
        ApiService api = retrofit.create(ApiService.class);
        Call<MovieData> call = api.getTopRateMovies("api_key");
        call.enqueue(new Callback<MovieData>() {
            @Override
            public void onResponse(Call<MovieData> call, Response<MovieData> response) {
                result.postValue(new NetworkResponse(response.body()));
            }

            @Override
            public void onFailure(Call<MovieData> call, Throwable t) {
                Log.e(TAG, t.getLocalizedMessage());
                result.postValue(new NetworkResponse(t));
            }
        });
        return result;
    }

Now in the ViewModel class I am doing this:

public class MovieListViewModel extends ViewModel {


    public LiveData<NetworkResponse> result, topRatedMovies;
    public LiveData<List<MovieEntity>> favoriteMovies;

    private Repository repository;

    public MovieListViewModel() {
        repository = new Repository(MyApplication.getInstance());
    }

    public void getTopRatedMovieList() {
        topRatedMovies = repository.getTopRatedMovies();
    }

}

Now in the MainActivity.java:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        ((MyApplication) getApplication()).getComponent().inject(this);
        movieListViewModel = ViewModelProviders.of(this).get(MovieListViewModel.class);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
        adapter = new MovieListAdapter(this);
        movieListViewModel.getTopRatedMovieList();
        observeTopRatedMovies();

    }
private void observeTopRatedMovies() {
        movieListViewModel.topRatedMovies.observe(this, new Observer<NetworkResponse>() {
            @Override
            public void onChanged(@Nullable NetworkResponse networkResponse) {
                if (networkResponse.getPostData() != null) {
                    Log.e(TAG, "Successful");
                    topRatedData = networkResponse.getPostData();
                    adapter.addData(networkResponse.getPostData().getResults());
                    recyclerView.setAdapter(adapter);
                } else {
                    Log.e(TAG, "failure");
                }
            }
        });
    }

Now everything works fine and I am able to see the list. But if I rotate the phone the viewmodel makes the network call again. How can I avoid the network call again on screen orientation change?


Solution

  • You can initialize live data only once. That should be enough:

    public class MovieListViewModel extends ViewModel {
    
    
        public LiveData<NetworkResponse> result, topRatedMovies;
        public LiveData<List<MovieEntity>> favoriteMovies;
    
        private Repository repository;
    
        public MovieListViewModel() {
            repository = new Repository(MyApplication.getInstance());
            topRatedMovies = repository.getTopRatedMovies();
        }
    
    }