Ad

Android Room + ViewModel Usage

I want to use android's Room + ViewModel components for my app, but I'm not quite sure how. One of my database tables is going to represent categories' entries. Number of categories is going to change depending on user, so I'm not creating different table for every category. I need to do some calculations on this data, one is sorting data in different lists, but it's gonna be relevant to all my fragments in app. And if i wanted to use live data for that, how do I do that?

All the examples i could find finally got or observed the data in activities/fragments. But given that i'm gonna need to do those calculations on this data and it's gonna be relevant to all fragments, should I get that data in my ViewModel and calculate everything there and just leave getters for my fragments?

What if i wanted to use LiveData for that, do I register the observer in VIewModel, calculate things in onChanged there, and create another LiveData from that in ViewModel and let fragments listen to that new LiveData?

And one more thing, if i end up using LiveData and I don't know how many categories are going to be there, do I listen to all table entries, and re-calculate everything once change is detected, or do I create different listeners based on "... WHERE CategoryID = :categoryID" to avoid re-calculating everything when only one category entry was added?

Ad

Answer

You should get that data in a ViewModel, process the data, and let that ViewModel instance shared by the Fragments. Check this part of the ViewModel guide to see how to share a ViewModels between fragments.


What if i wanted to use LiveData for that, do I register the observer in VIewModel, calculate things in onChanged there, and create another LiveData from that in ViewModel and let fragments listen to that new LiveData?

No. Instead, register observerd in ViewModel using LiveData.observeForever.

ExampleViewModel

class ExampleViewModel extends ViewModel {

    private final LiveData<Data> myLiveData;
    private final Observer<Data> myObserver;

    ExampleViewModel() {
        // Step 1: get LiveData and instantiate observer
        myLiveData = myRepository.getMyData();
        myObserver = (data) -> {...};

        // Step 2: use observeForever to observe the LiveData
        myLiveData.observeForever(myObserver);
    }


    @Override
    void onCleared () {
        // Step 3: remove observer
        myLiveData.removeObserver(myObserver);
    }
}


if i end up using LiveData and I don't know how many categories are going to be there, do I listen to all table entries, and re-calculate everything once change is detected, or do I create different listeners based on "... WHERE CategoryID = :categoryID" to avoid re-calculating everything when only one category entry was added?

Room knows when the table changes, but does not know how the table has changed, so it will re-calculate everything, even if you specify categoryID in the query and that specific category has not changed. Creating different listeners for each category will not reduce the computation cost, it will only make your logic more complex. You should instead listen to the entire table, or if the computation is too heavy, then not use LiveData and do some one-time look-ups.

Ad
source: stackoverflow.com
Ad