Repository method sets LiveData value inside Asynchronous Retrofit call

1.6k views Asked by At

When going through the official guide for the Android Architecture Components, in the section that explains the repository layer with a Retrofit request there is a piece of code I cannot seem to fully understand:

public class UserRepository {
    private Webservice webservice;
    // ...
    public LiveData<User> getUser(int userId) {
        // This is not an optimal implementation, we'll fix it below
        final MutableLiveData<User> data = new MutableLiveData<>();
        webservice.getUser(userId).enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                // error case is left out for brevity
                data.setValue(response.body());
            }
        });
        return data;
    }
}

At this stage we are initializing our LiveData object:

final MutableLiveData<User> data = new MutableLiveData<>();

Then in the retrofit asynchronous call, we set the value for that variable.

As this is an asynchronous call, wouldn't that method just return the data initialized but never with the value set?

2

There are 2 answers

0
stkent On BEST ANSWER

You are correct that the LiveData instance will likely be returned from the method you show before the asynchronous network request completes.

This would be a problem if enqueuing a network request was not sufficient to prevent it from being eligible for garbage collection. Since this is not the case, the network request will continue to execute after you exit your method. Once the request completes, the value will be "fed into" the LiveData instance that you returned (this is what the call to setValue does), and observers of that instance will then be notified.

0
Suleyman On

AFAIK, you will create a method in the ViewModel class, which will return the method you mentioned above from the repository, something like LiveData<User>getUser(). And because the Object returned from this function is wrapped in a LiveData you will be able to observe the changes in your Activity/Fragment:

 MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
    model.getUsers().observe(this, users -> {
        // update UI
    });

EDIT:

Obviously the answer by @stkent is much more precise and gives a clear reason why the code works.