Я играл с вашим приложением (спасибо за предоставленную ссылку на 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;
}
}
...