0

I am implementing an android project where i configure a service to connect to star wars api and request several characters from it. I am using MVVM architecuture. I am making requests through the searchCharacters method:

    public void searchCharacters(int queryPage) {
    Map<String, String> queryData = new HashMap<>();
    queryData.put("page", String.valueOf(queryPage));
    starWarsClient.createStarWarsService().getPeople(queryData).enqueue(new Callback<PeopleResponse>() {
        @Override
        public void onResponse(Call<PeopleResponse> call, Response<PeopleResponse> response) {
            Log.d("RESPONSE BODY", "CHARACTERS OF PAGE : " + String.valueOf(queryPage));
            if (response.body().getResults() != null) {
                List<Character> characters = response.body().getResults();
                if (response.body() != null) {
                    peopleResponseMutableLiveData.postValue(response.body());
                }
            }
        }

        @Override
        public void onFailure(Call<PeopleResponse> call, Throwable t) {
            peopleResponseMutableLiveData.postValue(null);

        }
    });

On charactersFragment (which sets the characterAdapter) and visualizes the recieved data, i am observing the liveData of the viewModel and listen for changes in the data with the onChanged() method:

        //intiialize the characterViewModel and connect the Live Data to the fragment
    characterSearchViewModel = ViewModelProviders.of(this).get(CharacterSearchViewModel.class);
    characterSearchViewModel.init();
    characterSearchViewModel.searchCharacters(1);
    characterSearchViewModel.searchCharacters(2);
    characterSearchViewModel.searchCharacters(3);
    characterSearchViewModel.searchCharacters(4);
    characterSearchViewModel.searchCharacters(5);
    characterSearchViewModel.searchCharacters(6);
    characterSearchViewModel.searchCharacters(7);
    characterSearchViewModel.searchCharacters(8);
    characterSearchViewModel.searchCharacters(9);
    characterSearchViewModel.getPeopleResponseLiveData().observe(this, new Observer<PeopleResponse>() {
                @Override
                public void onChanged(PeopleResponse peopleResponse) {
                    if (peopleResponse != null) {
                        if (peopleResponse.getPrevious() != null) {
                            Log.d("LIVE DATA CHANGED", " change of live data");
                        }
                        returnedCharacters = peopleResponse.getResults();
                        for (int i = 0; i < returnedCharacters.size(); i++)
                        {
                            AllCharacters.add(returnedCharacters.get(i));
                        }
                        //sort all characters before presenting them
                        Collections.sort(AllCharacters, new Comparator<Character>() {
                            @Override
                            public int compare(Character character, Character t1) {
                                return character.getName().compareTo(t1.getName());
                            }
                        });
                        charactersAdapter.setResults(AllCharacters);
                                        setRecyclerAdapter(AllCharacters);
                    }
                }
            });

The problem is that i am getting the response bodies of all the 9 queries (for each character page of the api), while the onChanged method of the Observer gets notified only once...is there a mismatch between the queries and the change of the LiveData? Have i misunderstood something, or is there a better way to implement this?

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • Have you checked with the debugger that your ```peopleResponseMutableLiveData.postValue(response.body());``` is invoked 9 times or only once? – Rajat Beck Jul 01 '20 at 17:19
  • Yes and it is called 9 times... – Lampros Marantos Jul 01 '20 at 17:34
  • live data's observe method is only called when there is a change in data, reason, why observer is not called multiple times, maybe due to ```PeopleResponse``` object is having the same data for all the 9 calls or you might need to override equals and hashcode method for your `PeopleResponse` class since Live Data is not able to differentiate between two different objects of same type. – Rajat Beck Jul 01 '20 at 17:41
  • Just add them in a loop and `.observe()` each of them when iterating... I don't know what you're trying to accomplish, but `MediatorLiveData` permits merging, as I wonder why you even request 9 times. – Martin Zeitler Jul 01 '20 at 17:42
  • Or try to override `peekContent()` to see if it may already have been handled. – Martin Zeitler Jul 01 '20 at 17:47
  • Since i am using the post(Value) on 9 different queries (with different response Bodies), should n't the program evoke the onChanged() method equal times? – Lampros Marantos Jul 01 '20 at 17:49
  • @MartinZeitler i am quering 9 different pages of the api so i am putting different page parameters on the retrofit api Call method. – Lampros Marantos Jul 01 '20 at 17:51

0 Answers0