Android: 我已经删除了我的数据,但是房间里还有一些数据

Android: i'm already delete my data, but in room still exists some data

我有 Boolean booleanCheckAvailabilityData 来检查我 activity 中的可用性数据以创建 add/remove 收藏夹。然后我创建

dataFavoriteMovieById = favoriteMovieViewModel.getAllFavoriteMovieById(idMovie);

通过id获取数据。所以我做了条件语句来检查可用性数据,然后将结果放入布尔值,稍后我使用布尔值来添加或删除收藏夹。

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

在第一个 运行 中,它起作用了。我的 dataFavoriteMovieById 为空

但是,在我添加或删除收藏后。它始终包含数据 (RoomTrackingLiveData)。

我该如何解决...

我的代码 link : https://github.com/komangss/Submission-Menjadi-Android-Developer-Expert/blob/master/app/src/main/java/com/dicoding/submissionmade2_1/activity/DetailMovieActivity.java

据我在您的代码中看到的情况 - getAllFavoriteMovieById 按预期工作。问题是 - 您将 LiveData 用作 getAllFavoriteMovieById 的 return 类型,因此它 return 不是值本身,而是 LiveData 包装器。但是,如果您尝试观察此 LiveData 对象,您将(大概是因为我还没有看到相关代码)收到 null 而不是 favorite 值。在这个观察者中为你的 booleanCheckAvailabilityData 赋值的唯一正确位置(当然取决于你的 DAO 代码)。

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

类似的东西(再次取决于您的 DAO 代码和 getAllFavoriteMovieById 实现) 希望对你有帮助。

ROOM 中尝试删除 旧的 TABLE,然后再插入新数据。在这种情况下,旧数据将被删除,因为我们正在删除旧数据

我玩过您的应用程序(感谢您提供 github link),这是我的结果。

最新的应用程序版本

您的最新实施不再产生 NPE,因为您以更一致的方式使用 getAllFavoriteMovieById。您不再自己初始化 FavoriteMovieRepository 中的 LiveData 实例,而是将其委托给 Room 为您完成。因此,您不会获得 NPE,因为 Room 将始终创建 return 结果的列表。如果没有项目,它将 return 一个空列表。因此,您可以在此处安全地删除 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 因为你 return 在 favoriteMovieById LiveData 在你的 [=25= 中实际初始化之前编辑了它].

所以,这里详细介绍了发生的事情。首先,一旦创建了 DetailMovieActivityfavoriteMovieViewModel 就会调用 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 并 returned 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;
    }
}
...