Android: я уже удалил свои данные, но в комнате все еще есть некоторые данные - PullRequest
2 голосов
/ 03 февраля 2020

У меня есть Boolean booleanCheckAvailabilityData , чтобы проверить данные о доступности в моей деятельности для создания добавления / удаления избранного. затем я создаю

dataFavoriteMovieById = favoriteMovieViewModel.getAllFavoriteMovieById(idMovie);

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

if (dataFavoriteMovieById == null) {
    booleanCheckAvailabilityData = false;
} else {
    booleanCheckAvailabilityData = true;
}

В первом запуске это работает. my dataFavoriteMovieById равно нулю

My First run

Но после того, как я добавляю или удаляю избранное. он всегда всегда содержит данные ( RoomTrackingLiveData ).

it contain RoomTrackingLiveData

Как я могу решить эту проблему ...

мой код ссылки: https://github.com/komangss/Submission-Menjadi-Android-Developer-Expert/blob/master/app/src/main/java/com/dicoding/submissionmade2_1/activity/DetailMovieActivity.java

Ответы [ 3 ]

1 голос
/ 08 февраля 2020

Я играл с вашим приложением (спасибо за предоставленную ссылку на github), и вот мои результаты.

Последняя версия приложения

Ваша последняя реализация больше не производит NPE, так как вы используете getAllFavoriteMovieById более последовательным образом. Вы больше не инициализируете экземпляр LiveData в FavoriteMovieRepository самостоятельно, а делегируете его в Room, чтобы сделать это за вас. Таким образом, вы не получите NPE, поскольку Room всегда будет создавать список для возврата результатов. Если элементов нет, будет возвращен пустой список. Таким образом, вы можете безопасно удалить try/catch здесь:

try {
    favoriteMovieViewModel.getAllFavoriteMovieById(idMovie).observe(this, new Observer<List<FavoriteMovie>>() {
        @Override
        public void onChanged(List<FavoriteMovie> favoriteMovies) {
            booleanCheckAvailabilityData = favoriteMovies.size() != 0;
        }
    });

} catch (NullPointerException e) {
    Log.d("ini bug nya", e.getMessage());
}

Оригинальная версия приложения

В дополнение к тому, что @Paul Ost сказал о том, как favoriteMovieViewModel следует использовать правильно (слушая к нему, не используя его напрямую), я объясню, почему у вас на самом деле был NPE.

В этой версии вы работали с NullPointerException, потому что вы вернули favoriteMovieById LiveData до того, как он был фактически инициализируется в вашем GetFavoriteMovieByIdAsyncTask.

Итак, вот что происходило в деталях. Во-первых, как только ваш DetailMovieActivity был создан, favoriteMovieViewModel называется getAllFavoriteMovieById(), как показано ниже:

DetailMovieActivity. java

...
favoriteMovieViewModel = ViewModelProviders.of(this).get(FavoriteMovieViewModel.class);
dataFavoriteMovieById = favoriteMovieViewModel.getAllFavoriteMovieById(idMovie);
...

FavoriteMovieViewModel. java

* Экземпляр 1034 *FavoriteMovieViewModel, в свою очередь, делегировал вызов экземпляру FavoriteMovieRepository, как показано ниже:
public LiveData<List<FavoriteMovie>> getAllFavoriteMovieById(int idMovie) {
    return repository.getFavoriteMovieById(idMovie);
}

FavoriteMovieRepository. java

Наконец, getFavoriteMovieById запустил GetFavoriteMovieByIdAsyncTask и вернул favoriteMovieById:

public LiveData<List<FavoriteMovie>> getFavoriteMovieById(int id_movie) {
    new GetFavoriteMovieByIdAsyncTask(favoriteMovieDao).execute(id_movie);
    return favoriteMovieById;
}

Но это неправильно , так как ваш любимыйMovieById был установлен в null по умолчанию, и так при первом запуске Вы всегда получали это.

Ваш AsyncTask в итоге установил ненулевое значение, но было слишком поздно:

...
private static class GetFavoriteMovieByIdAsyncTask extends AsyncTask<Integer, Void, Void> {
  ... 
    @Override
    protected Void doInBackground(Integer... integers) {
        FavoriteMovieRepository.favoriteMovieById = favoriteMovieDao.getFavoriteMovieById(integers[0]);
        return null;
    }
}
...
1 голос
/ 05 февраля 2020

Из того, что я вижу в вашем коде - getAllFavoriteMovieById работает как положено. Дело в том, что вы используете LiveData в качестве типа возврата getAllFavoriteMovieById, поэтому он возвращает не само значение, а оболочку LiveData. Но если вы попытаетесь наблюдать за этим LiveData объектом, вы (вероятно, так как я не видел соответствующего кода) получите нуль вместо любимого значения. Единственное правильное место для присваивания значения вашему booleanCheckAvailabilityData внутри этого наблюдателя (конечно, в зависимости от вашего кода DAO).

favouriteMovieViewModel.getAllFavoriteMovieById().observe(this, Observer { data ->
        if (data == null) {
            booleanCheckAvailabilityData = false;
        } else {
            booleanCheckAvailabilityData = true;
        }
})

Нечто подобное (опять же, это зависит от вашего кода DAO и getAllFavoriteMovieById реализация) Надеюсь, что это помогает.

0 голосов
/ 06 февраля 2020

In ROOM Попробуйте удалить old TABLE перед вставкой новых данных. В этом случае старые данные будут удалены, так как мы удаляем старые данные

...