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
Android - Build Separate APKs for Different Processor Architectures
How to Change Images on Imageview After Some Interval
Out of Memory While Creating Bitmaps on Device
Differencebetween Sendstickybroadcast and Sendbroadcast in Android
What Does the Filter Parameter to Createscaledbitmap Do
Android: Cloning a Drawable in Order to Make a Statelistdrawable with Filters
Change Expandable Indicator in Expandablelistview
Layout Weights Do Not Work Inside a Scrollview
How to Use Sharedpreferences to Save More Than One Values
Is Deprecated Word the Only Difference Between Fill_Parent and Match_Parent
How to Create and Save a Screenshot from a Surfaceview
How to Filter the Data in Realm Adapter
Finding Current Location of the User in Android
Where Is the All Android Broadcast Intent List