Room - Livedata Observer Does Not Trigger When Database Is Updated

Room - LiveData observer does not trigger when database is updated

I had a similar problem using Dagger 2 that was caused by having different instances of the Dao, one for updating/inserting data, and a different instance providing the LiveData for observing. Once I configured Dagger to manage a singleton instance of the Dao, then I could insert data in the background (in my case in a Service) while observing LiveData in my Activity - and the onChange() callback would be called.

It comes down to the instance of the Dao must be the same instance that is inserting/updating data and providing LiveData for observation.

Android Room LiveData Observer not updating

Check your database singleton implementation, since variable INSTANCE there - is always null. You should set it at first time when you've got the instance of the class. Otherwise your app has a deal with different instances of your Database class.

Probably that causes a problem, when though some changes were made to database, but LiveData's observer for these changes was not triggered.

Android Fragment LiveData observer is not triggered when update is done on a record data

I found the solution, the problem was not in the LiveData code, but in the Recyclerview ListAdapter & DiffUtil Implementation which stopped from triggering LiveData change.

In MyGoalsAdapter I have used DiffUtil & ListAdapter to have smooth animations and increase performance. For it to work properly we need to compare the new list with the old list. The Problem is where the contents of an object were being marked as equal when they were actually different. I solved this by adding a date field in my Model class modifiedAt
and updated the field before that Object was updated. Here is the snippet of code to explain it better.

MyGoalsAdapter:

public class MyGoalsAdapter extends ListAdapter<Goal, MyGoalsAdapter.MyGoalsViewHolder> {
private Context context;

public MyGoalsAdapter() {
super(DIFF_CALLBACK);
}

private static final DiffUtil.ItemCallback<Goal> DIFF_CALLBACK = new DiffUtil.ItemCallback<Goal>() {
@Override
public boolean areItemsTheSame(@NonNull Goal oldItem, @NonNull Goal newItem) {
return oldItem.getId() == newItem.getId();
}

@Override
public boolean areContentsTheSame(@NonNull Goal oldItem, @NonNull Goal newItem) { //Here we check if the objects in the list have changed fields.
boolean id,desc,iscomp,edate,etime,sdate,stime,title, naya, purana, createdAt, modifiedAt;

id = oldItem.getId() == newItem.getId();
desc = oldItem.getDescription().equals(newItem.getDescription());
purana = oldItem.isCompleted();
naya = newItem.isCompleted();
iscomp = purana && naya;
edate = oldItem.getEnd_date().equals(newItem.getEnd_date());
etime = oldItem.getEnd_time().equals(newItem.getEnd_time());
sdate = oldItem.getStart_date().equals(newItem.getStart_date());
stime = oldItem.getStart_time().equals(newItem.getStart_time());
title = oldItem.getTitle().equals(newItem.getTitle());
createdAt = oldItem.getCreatedAt().equals(newItem.getCreatedAt());
modifiedAt = oldItem.getModifiedAt().equals(newItem.getModifiedAt()); //This will return false for the object that is changed

return id &&
desc &&
iscomp &&
edate &&
etime &&
sdate &&
stime &&
title &&
createdAt &&
modifiedAt
;
}
};
}

When I am updating I set the Object modifiedAt field with the current Date and Time.

Goal tempGoal = myGoalsAdapter.getGoalAt(viewHolder.getAdapterPosition()); //Get the object to make change to it

//make change to the object's field

tempGoal.setModifiedAt(Calendar.getInstance().getTime()); //set the modified date with Current date
myGoalsViewModel.updateGoal(tempGoal); //Update the object to the database

Changing the modifiedAt field will tell the Adapter when there is an object that is updated, triggering the animation and showing the updated object in the List, instantly.

I hope this will help someone.

Room - LiveData not triggered

The problem was inside AppCompatActivity which holds ViewModel with LiveData.

LiveData observer has been called only for Fragment, not for Activity.
I used AppCompatActivity with LifecycleOwner interface implemented, but correct is to implement LifecycleRegistryOwner.

Credits: https://issuetracker.google.com/issues/63764057



Related Topics



Leave a reply



Submit