Метод репозитория устанавливает значение 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 гораздо точнее и дает четкую причину, почему код работает.

Другие вопросы по тегам