LiveData does not update data from one activity to another - Android
I have 2 Activity
viz
- List
Activity
- More details
Activity
The list Activity
shows a list of items, and the detail is Activity
displayed when you click on an item from the list. In ListActivity
we are watching fetching feeds from the database, and as soon as we do that, we update the user interface.
List page
feedViewModel.getFeeds().observe(this, Observer { feeds ->
feeds?.apply {
feedAdapter.swap(feeds)
feedAdapter.notifyDataSetChanged()
}
})
We now have a page DetailActivity
that updates the feed (item) and Activity
, but the changes are not reflected in the ListActivity
.
Detail page
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
feedViewModel.setFeedId(id)
feedViewModel.updateFeed()
}
Channel View Model
class FeedViewModel(application: Application) : AndroidViewModel(application) {
private val feedRepository = FeedRepository(FeedService.create(getToken(getApplication())),
DatabaseCreator(application).database.feedDao())
/**
* Holds the id of the feed
*/
private val feedId: MutableLiveData<Long> = MutableLiveData()
/**
* Complete list of feeds
*/
private var feeds: LiveData<Resource<List<Feed>>> = MutableLiveData()
/**
* Particular feed based upon the live feed id
*/
private var feed: LiveData<Resource<Feed>>
init {
feeds = feedRepository.feeds
feed = Transformations.switchMap(feedId) { id ->
feedRepository.getFeed(id)
}
}
/**
* Get list of feeds
*/
fun getFeeds() = feeds
fun setFeedId(id: Long) {
feedId.value = id
}
/**
* Update the feed
*/
fun updateFeed() {
feedRepository.updateFeed()
}
/**
* Get feed based upon the feed id
*/
fun getFeed(): LiveData<Resource<Feed>> {
return feed
}
}
For simplicity, some code has been abstracted. If necessary, I can add them to track the problem
source to share
After a lot of research and some idea from this answer from another question. I figured out the problem.
Question
DatabaseCreator(application).database.feedDao()
did not create a single instance of the database, due to which the first Activity
had a different instance where it was LiveData
listening for changes, and the second Activity
had a different instance where after the data was updated the callback was ignored.
Decision
Use dagger or any other dependency injection to ensure that only one instance of the database and DAO is created.
source to share
I faced this same problem in multiple steps for the same objects. I found it helpful to code the Database Database instance as a Singleton like: this (step 5)
Example:
public abstract class MyDatabase extends RoomDatabase {
private static MyDatabase mMyDatabase;
public static MyDatabase getInstance(Context context) {
if(mMyDatabase==null){
mMyDatabase = Room.databaseBuilder(context.getApplicationContext(), MyDatabase.class, "app_database").build();
return mMyDatabase;
}
}
}
And in each ViewModel you have (class extends from AndroidViewModel for Context parameter):
public MyViewModel(@NonNull Application application) {
super(application);
mMyDatabase = MyDatabase.getInstance(application.getApplicationContext());
}
Now, in my case, every time I edit a value in the config actions, it is reflected in other actions.
Hope for this help.
source to share