我有Boolean booleanCheckAvailabilityData来检查我的 Activity 中的可用性数据以创建添加/删除收藏夹。然后我创建
dataFavoriteMovieById = favoriteMovieViewModel.getAllFavoriteMovieById(idMovie);
通过id获取数据。因此,我创建条件语句来检查可用性数据,然后将结果放入 bool 值,稍后使用该 bool 值来添加或删除收藏夹。
if (dataFavoriteMovieById == null) {
booleanCheckAvailabilityData = false;
} else {
booleanCheckAvailabilityData = true;
}
第一次运行时,它有效。我的 dataFavoriteMovieById 为空
但是,在我添加或删除收藏夹之后。它始终包含数据 (RoomTrackingLiveData)。
我该如何解决这个问题...
最佳答案
我使用了您的应用程序(感谢您提供 github 链接),这是我的结果。
最新应用版本
由于您以更一致的方式使用 getAllFavoriteMovieById
,因此您最新的实现不再产生 NPE。您不再需要自己初始化 FavouriteMovieRepository
中的 LiveData
实例,而是将其委托(delegate)给 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
实例又将调用委托(delegate)给 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;
}
}
...
关于Android:我已经删除了我的数据,但房间里仍然存在一些数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60032722/