首页 > 解决方案 > Android Room 数据库 ViewModel 不反映同步插入的数据

问题描述

我遇到了一个问题,即写入我的 Room 数据库的数据不会出现在 ViewModel 中,即使我是同步写入的。

这是日志的样子:

com.widget D/WriteActivity: Writing widget data to the database
com.widget D/WriteActivity: Starting the ReadActivity
com.widget D/ReadActivity: Got a new list of 0 objects

情况如下:

我有两个活动,WriteActivityReadActivity。在里面ReadActivity我有一个ViewModel监听数据库更改(onCreate在 Activity 的方法中实例化):

    // observe the widget data
    WidgetViewModel widgetViewModel = ViewModelProviders.of(this).get(
            WidgetViewModel.class);
    widgetViewModel.getAllWidgets().observe(this, new Observer<List<Widget>>() {
        @Override
        public void onChanged(@Nullable final List<Widget> updatedWidgets) {

            Log.d(TAG, "Got a new list of " + updatedWidgets.size() + " objects");
        }
    });

WriteActivity我有代码在后台线程上将对象添加到数据库中,然后,一旦完成,它就会启动ReadActivity

    // persist the objects to the room database (doInBackground)
    WidgetRepository myObjectRepository = new WidgetRepository(getApplication());
    myObjectRepository.insert(myObjects); // myObjects is a list of 5 objects

    // load the ReadActivity (onPostExecute)
    Intent myIntent = new Intent(WriteActivity.this, ReadActivity.class);
    WriteActivity.this.startActivity(myIntent);

这是我的 DAO:

@Dao
public interface WidgetDao {

     @Query("SELECT * FROM widget_table")
     LiveData<List<Widget>> getAll();

     @Insert(onConflict = OnConflictStrategy.REPLACE)
     void insert(Widget... widgets);
}

我的数据库:

@Database(entities = {Widget.class}, version = 1, exportSchema = false)
public abstract class WidgetDatabase extends RoomDatabase {
    public abstract WidgetDao widgetDao();

    private static volatile WidgetDatabase INSTANCE;

    static WidgetDatabase getDatabase(final Context context) {

        if (null == INSTANCE) {
            synchronized (WidgetDatabase.class) {
                if (null == INSTANCE) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        WidgetDatabase.class, "widget_database")
                        .build();
                }
            }
        }

        return INSTANCE;
    }
}

我的存储库:

public class WidgetRepository {

    private final WidgetDao widgetDao;
    private final LiveData<List<Widget>> widgets;

    public WidgetRepository(Application application) {
        WidgetDatabase db = WidgetDatabase.getDatabase(application);
        widgetDao = db.widgetDao();
        widgets = widgetDao.getAll();
    }

    public LiveData<List<Widget>> getWidgets() {
        return widgets;
    }

    public void insert(List<Widget> widgetsToInsert) {
        widgetDao.insert(widgetsToInsert.toArray(
                new Widget[widgetsToInsert.size()]));
    }

我的视图模型:

public class WidgetViewModel extends AndroidViewModel {

        private final LiveData<List<Widget>> widgets;

        public WidgetViewModel (Application application) {
            super(application);
            WidgetRepository widgetRepository = new WidgetRepository(application);
            widgets = widgetRepository.getWidgets();
        }

        public LiveData<List<Widget>> getAllWidgets() { return widgets; 
    }
}

标签: androidandroid-room

解决方案


你的问题是LiveData<List<Widget>>没有被通知。

那么,如何更新呢?

见下文,

更新 LiveData 对象

LiveData没有公开可用的方法来更新存储的数据。该类MutableLiveData公开了setValue(T)postValue(T) 方法,如果您需要编辑存储在LiveData对象中的值,则必须使用这些方法。通常MutableLiveData在 ViewModel 中使用,然后 ViewModel 只向观察者公开不可变的 LiveData 对象。

因此,您可以对ViewModel:

public class WidgetViewModel extends AndroidViewModel {

    private final MutableLiveData<List<Widget>> widgets = new MutableLiveData<List<Widget>>(); // Make it mutable livedata

    public WidgetViewModel (Application application) {
        super(application);
        WidgetRepository widgetRepository = new WidgetRepository(application);
        //widgets = widgetRepository.getWidgets();
        //use this to update your live data instead,
        widgets.setValue(widgetRepository.getWidgets().getValue()); // This will update your live data, use like this for future updates.
    }

    public LiveData<List<Widget>> getAllWidgets() { return widgets; 
}
}

从这里结帐更多


推荐阅读