LiveData изначально не показывает данные

Я беру некоторые данные со своего сервера и наблюдаю за ними с помощью LiveData. Когда мой фрагмент запускается изначально, он ничего не возвращает в onChanged(), а после переключения фрагмента запускает onChanged() с правильными данными.

После отладки я увидел, что мой вызов API прошел успешно, и я получаю там данные, но изначально он не возвращает данные через onChanged().

Репозиторий:

public class UserRepository {
    private ApiService apiService;
    private static UserRepository repository;
    private MutableLiveData<User> user = new MutableLiveData<>();

    private UserRepository() {
        apiService = RestClient.getClient().create(ApiService.class);
    }

    public synchronized static UserRepository getInstance() {
        if (repository == null) repository = new UserRepository();
        return repository;
    }

    public LiveData<User> getUser() {
        return user;
    }

    public void fetchUser() {
        Call<User> call = apiService.getUser();
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
                if (response.body() != null) user.postValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
                user.postValue(null);
                t.printStackTrace();
            }
        });
    }
}

ViewModel:

public class UserViewModel extends AndroidViewModel {
    private LiveData<User> user;

    public UserViewModel(@NonNull Application application) {
        super(application);
        user = UserRepository.getInstance().getUser();
    }

    public LiveData<User> getUser() {
        return user;
    }
}

Фрагмент:

userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser.observe(this, user -> {
    //Set data
})

Я могу решить эту проблему, позвонив UserRepository.getInstance().getUser() перед наблюдением в моем фрагменте. Но это не самый предпочтительный метод, как заявляет Google, и своего рода обходной путь.

Вместо postValue() попробуйте метод setValue().

Jeel Vankhede 04.12.2018 14:57

@JeelVankhede Не сработало

RandomyzeEverything 04.12.2018 14:58

Можете ли вы поделиться своей настройкой во фрагменте?

Jeel Vankhede 04.12.2018 15:02

@JeelVankhede Я отредактировал код фрагмента. Я звоню в onCreateView()

RandomyzeEverything 04.12.2018 15:05

Где вы называете метод fetchUser() во фрагменте? может быть, вы звоните ему после наблюдения за своими данными, поэтому вы получаете отсроченное наблюдение!

Jeel Vankhede 04.12.2018 15:12

Если я позвоню UserRepository.getInstance().fetchUser() перед наблюдением, все будет нормально. Но Google не рекомендует вызывать репозиторий из фрагментов.

RandomyzeEverything 04.12.2018 16:29
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
272
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как уже упоминалось в комментариях, вы, кажется, вызываете getUser () в репозитории еще до того, как устанавливаете какое-либо значение в fetchUser (). Измените fetchUser () так, чтобы он возвращал LiveData, а затем вызовите этот метод из модели представления вместо getUser ():

public LiveData<User> fetchUser() {
    Call<User> call = apiService.getUser();
    call.enqueue(new Callback<User>() {
        @Override
        public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
            if (response.body() != null) user.postValue(response.body());
        }

        @Override
        public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
            user.postValue(null);
            t.printStackTrace();
        }
    });

    return user;
 }

А затем в модели представления:

public UserViewModel(@NonNull Application application) {
    super(application);
    user = UserRepository.getInstance().fetchUser();
}

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