向Room数据库存数据后RecyclerView不更新的解决方法
解决Room数据库添加数据后RecyclerView不更新的问题
问题
开发食谱管理APP时,将食谱存储到Room数据库,主HomeFragment通过RecyclerView展示数据。每次添加新食谱到数据库后,RecyclerView不会自动刷新,只有重启APP才能看到新条目。
问题根源
- 数据库实例不一致:HomeFragment中自行创建了
RecipeDatabase实例,而ViewModel使用的是单例模式的RecipeDatabase.getInstance(application),两个实例相互独立。添加数据的操作在HomeFragment的实例中执行,ViewModel监听的却是另一个实例的LiveData,因此数据变化无法被感知。 - 数据插入未通过ViewModel:直接使用独立的DB实例插入数据,没有和ViewModel关联的数据源打通,导致LiveData无法触发更新回调。
修复步骤
1. 在ViewModel中添加数据插入方法
修改recipeModel(ViewModel),添加插入食谱的方法,确保操作的是单例数据库实例,并在后台线程执行:
public class recipeModel extends AndroidViewModel{ RecipeDAO recipeDAO; RecipeDatabase recipeDB; LiveData<List<Recipe>> allRecipes; public recipeModel(Application application) { super(application); recipeDB = RecipeDatabase.getInstance(application); recipeDAO = recipeDB.getRecipeDAO(); allRecipes = recipeDAO.getAllRecipes(); } LiveData<List<Recipe>> getAllRecipes() { return allRecipes; } // 新增:插入食谱的方法,后台线程执行 public void insertRecipe(Recipe recipe) { new Thread(() -> recipeDAO.addRecipe(recipe)).start(); } }
2. 移除HomeFragment中独立的数据库实例
删除HomeFragment中自行创建RecipeDatabase的代码,统一通过ViewModel操作数据库:
// 移除以下代码块 /* RoomDatabase.Callback myCallBack = new RoomDatabase.Callback() { @Override public void onCreate(@NonNull SupportSQLiteDatabase db) { super.onCreate(db); } @Override public void onOpen(@NonNull SupportSQLiteDatabase db) { super.onOpen(db); } }; recipeDB = Room.databaseBuilder(requireContext(), RecipeDatabase.class, "recipeDB").addCallback(myCallBack).build(); */
3. 修改数据插入逻辑,通过ViewModel执行
修改HomeFragment中的addNewRecipe方法,调用ViewModel的insertRecipe方法,不再自行操作数据库:
public void addNewRecipe(Recipe recipe){ // 调用ViewModel的插入方法 recipeViewModel.insertRecipe(recipe); requireActivity().runOnUiThread(() -> Toast.makeText(requireContext(), "添加到数据库", Toast.LENGTH_SHORT).show() ); }
原理说明
Room会自动监听数据库变化,当通过ViewModel的单例DB实例插入数据后,getAllRecipes()返回的LiveData会自动更新,触发HomeFragment中的观察者回调,调用适配器的setRecipe方法更新RecyclerView。
内容的提问来源于stack exchange,提问作者StevenH
相关产品推荐
相关产品推荐

