Android Room数据库ViewModel无法反映同步插入的数据

时间:2018-09-20 20:03:49

标签: android android-room

我遇到一个问题,即使我正在同步编写数据,但写入到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监听数据库更改(在Activity的onCreate方法中实例化):

    // 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()]));
    }

我的ViewModel:

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; 
    }
}

2 个答案:

答案 0 :(得分:0)

您的问题是未通知 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; 
}
}

here中查看更多信息

答案 1 :(得分:0)

我知道发生了什么事。真令人尴尬...当我问我的问题时,我对LiveData的工作原理有一个基本的误解。 RTFM jeez :)

阅读文档后,我得到了一个惊人的启示:LiveData与活动的生命周期相关。在我给出的示例中,我试图在onResume的{​​{1}}期间访问ViewModel,因为我想确保UI正确更新。新秀错误。像傻瓜一样,我相信Observer回调只会在LiveData封装的数据被修改时才会触发。实际上,活动变为活动状态时,无论数据是否更改,都将调用Observer中的LiveData回调,因此无需尝试在ReadActivity生命周期方法中手动进行任何操作。只需等待观察者的onResume回调并在那时更新UI。

应用程序现在运行良好,感谢所有阅读我的问题的人。