Recently I am exploring Android Architecture, that has been introduced recently by google. From the Documentation I have found this:
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<Users>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// do async operation to fetch users
}
}
the activity can access this list as follows:
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
My Question is, in the loadUsers()
function I am fetching the data asynchronously where I will first check the database(Room) for that data, If I do not get the data there I will make an API call to fetch the data from the web server. Then I will insert the fetched data into the database(Room) and update the UI according the data. What is the recommended approach to do this?
If I start a Service
to call the API from the loadUsers()
method, how can I update the MutableLiveData<List<User>> users
variable from that Service
?
If the app is fetching user data on a background thread, postValue (rather than setValue) will be useful.
In the loadData method there is a reference to the MutableLiveData "users" object. The loadData method also fetches some fresh user data from somewhere (for example, a repository).
Now, if execution is on a background thread, MutableLiveData.postValue() updates outside observers of the MutableLiveData object.
Maybe something like this:
I am assuming that you are using android architecture components. Actually it doesn't matter wherever you are calling
service, asynctask or handler
to update the data. You can insert the data from the service or from the asynctask usingpostValue(..)
method. Your class would look like this:As the
users
isLiveData
,Room
database is responsible for providing users data wherever it is inserted.Note:
In MVVM like architecture, the repository is mostly responsible for checking and pulling local data and remote data.Take a look at the Android architecture guide that accompanies the new architecture modules like
LiveData
andViewModel
. They discuss this exact issue in depth.In their examples they don't put it in a service. Take a look at how they solve it using a "repository" module and Retrofit. The addendums at the bottom include more complete examples including communicating network state, reporting errors, etc.
Please, use live data's postValue(..) method from background thread.
https://developer.android.com/topic/libraries/architecture/guide.html
Has very good answers for your problem. Scroll all the way to the bottom to see how you can save the response in your database and update the UI using the LiveData.