При вызове API LiveData сначала возвращает старое значение, а затем новое - PullRequest
1 голос
/ 12 февраля 2020

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

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

То, что я хочу, это чтобы он показывал только новый.

Переменные (viewModel, repository, и т. д. c) происходят из кинжала.

Основная активность:

viewModel.getPointGeoLocation(changedyPoints.get(0)).observe(this, new Observer<LatLng>() {
                @Override
                public void onChanged(@Nullable LatLng latLng) {
                    if (latLng != null) {...} else {...}}});

Класс ViewModel:

public LiveData<LatLng> getPointGeoLocation(Point Point) {
    repository.fetchGeoLocationCoordinates(Point);
    return repository.getPointGeoLocationNetworkSource();
}

Класс RepositoryImpl:

@Override
public void fetchGeoLocationCoordinates(Point Point) {
    pointNetworkDataSource.fetchGeoLocations(point);
}    

@Override
public LiveData<LatLng> getPointGeoLocationNetworkSource() {
   return pointNetworkDataSource.getPointGeoLocationData();
}

Класс NetworkDataSource:

public void fetchGeoLocations(Point point) {
    executors().getNetworkIO().execute(new Runnable() {
        @Override
        public void run() {
            AuthTokenUtil.waitForAuthToken(authTokenRepository);
            AuthToken authToken = authTokenRepository.getAuthToken().getValue();
            if (authToken.isValid()) {
                pointBackendApi.getGeoLocations(authToken.getToken(), point,
                        new PointBackendApi.GeoLocationHandler() {
                            @Override
                            public void update(LatLng latLng) {
                                pointGeoLocationData.postValue(latLng);
                            }
                        });
            } else {
                Log.d(TAG, "invalid auth token");
            }
        }
    });
}

public LiveData<LatLng> getPointGeoLocationData() {
    return pointGeoLocationData;
}

И, наконец, API-интерфейс внутреннего интерфейса:

@Override
public void getGeoLocations(String token, Point point, GeoLocationHandler geoLocationHandler) {
    http.getJson(POINT_GET_GEO_LOCATION_UPDATE, token, point.domesticAddress.formattedString, new Callback() {
        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) {
            try (ResponseBody body = response.body()) {
                if (body == null || body.contentLength() == 0) {
                    Log.d(TAG, "received no response");
                    return;
                }

                String res = body.string();
                LatLng result = new Gson().fromJson(res, LatLng.class);
                if (result != null && (result.latitude != 0 && result.longitude != 0)) {
                    Log.i(TAG, "received" + " points" + result.toString());
                    geoLocationHandler.update(result);
                } else {
                    geoLocationHandler.update(null);
                    Log.d(TAG, "Received 0, 0 coordinates");
                }
            } catch (Exception ex) {
                Log.e(TAG, ex.getMessage() != null ? ex.getMessage() : "HTTP problem");
            }
        }

        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            Log.w(TAG, "get failed");
        }
    });
}

Так что в основном, если у меня был ответ со значением * 103 1 * до, а затем снова вызвать этот API, он сначала вернет null, а затем вернет правильный ответ.

Первый метод viewModel.getPointGeoLocation() вызывается несколько раз, так что это может быть проблемой, но для меня это кажется что он должен быть внутри метода и действовать при нажатии кнопки, потому что метод, в котором он находится, содержит много данных, которые onChanged() должен использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...