Android: Infinite loop with LiveData

This gets called when a button is clicked

@Override
public void onFavoriteIconClicked() {
    viewModel.isFavoriteExist(test.getId()).observe(getViewLifecycleOwner(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            viewModel.isFavoriteExist(test.getId()).removeObserver(this);

            if (aBoolean) {

                binding.addToFavorite.setImageResource(R.drawable.non_fav);
                viewModel.delete(test);
            } else if (getActivity() != null) {
                Test test2 = new Test(test.getId(), test.getName());
                viewModel.insert(test2);
                binding.addToFavorite.setImageResource(R.drawable.fav);
            }
        }
    });
}

If the test object exists in the Favorite database, I have to delete it. After deleting, it calls this again (since it observed a chane) and inserts it again.

It keeps looping infinitely. Is there a better way to implement this or stop this?

Answer

It seems like some business logic has entered your view (Activity) class.

Since LiveData & Room are meant to use for receiving updates about Database changes, and your use of the DB is not requiring constant updates, I would suggest going with a more direct approach.

First, Remove the use of LiveData from your Database. Use simple return values.

Your view (Activity/Fragment) can then tell the view model that a button was clicked.

@Override
public void onFavoriteIconClicked() {
     viewModel.onFavoriteClicked()
}

The view will observe the view model in order to receive the correct icon to show.

Something like:

viewModel.favoriteIcon.observe(getViewLifecycleOwner(), new Observer<Integer>() { 
    @Override
    public void onChanged(Integer iconResId) {
         binding.addToFavorite.setImageResource(iconResId)
    }
 }

Now the viewModel can handle the logic (or better add a Repository layer – See Here)

Upon click, Check if entry exist in DB.
If exists: remove it from DB and set favoriteIcon value:

favoriteIcon.setValue(R.drawable.non_fav)

If doesn’t exist: Add it to DB and set favoriteIcon value.

favoriteIcon.setValue(R.drawable.fav)

For a good tutorial about using Room & LiveData – as well as doing so using the View/ViewModel/Repository pattern, check this link