Метод репозитория устанавливает значение LiveData в вызове Asynchronous Retrofit
При ознакомлении с официальным руководством по компонентам архитектуры Android в разделе, где поясняется уровень хранилища с запросом на модернизацию, есть фрагмент кода, который я не могу полностью понять:
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;
}
}
На этом этапе мы инициализируем наш LiveData
объект:
final MutableLiveData<User> data = new MutableLiveData<>();
Затем в модифицированном асинхронном вызове мы устанавливаем значение для этой переменной.
Поскольку это асинхронный вызов, не будет ли этот метод просто возвращать инициализированные данные, но никогда с заданным значением?
2 ответа
Вы правы в том, что LiveData
экземпляр, скорее всего, будет возвращен из показанного вами метода до завершения асинхронного сетевого запроса.
Это было бы проблемой, если бы постановка в очередь сетевого запроса была недостаточной, чтобы помешать ему иметь право на сборку мусора. Поскольку это не так, сетевой запрос продолжит выполняться после выхода из вашего метода. Как только запрос завершится, значение будет "подано" в LiveData
экземпляр, который вы вернули (это то, что вызов setValue
делает), и наблюдатели этого экземпляра будут уведомлены.
AFAIK, вы создадите метод в классе ViewModel, который будет возвращать упомянутый выше метод из репозитория, что-то вроде LiveData<User>getUser()
, И потому, что объект, возвращаемый из этой функции, обернут в LiveData
вы сможете наблюдать за изменениями в вашей деятельности / фрагменте:
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
РЕДАКТИРОВАТЬ:
Очевидно, что ответ @stkent гораздо точнее и дает четкую причину, почему код работает.