我玩过你的应用(感谢提供 github 链接),这是我的结果。
最新应用版本
您的最新实现不再产生 NPE,因为您以更一致的方式使用 getAllFavoriteMovieById。您不再自己在FavoriteMovieRepository 中初始化LiveData 实例,而是将其委托给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,因为您在 GetFavoriteMovieByIdAsyncTask 中实际初始化之前返回了 favoriteMovieById LiveData。
所以,这里详细介绍了正在发生的事情。首先,一旦你的DetailMovieActivity 被创建,favoriteMovieViewModel 调用getAllFavoriteMovieById() 如下:
DetailMovieActivity.java
...
favoriteMovieViewModel = ViewModelProviders.of(this).get(FavoriteMovieViewModel.class);
dataFavoriteMovieById = favoriteMovieViewModel.getAllFavoriteMovieById(idMovie);
...
FavoriteMovieViewModel.java
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;
}
但那是错误,因为您的 favoriteMovieById 默认设置为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;
}
}
...