我遇到一个问题,即使我正在同步编写数据,但写入到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
这里是情况:
我有两个活动,WriteActivity
和ReadActivity
。在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;
}
}
答案 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。
应用程序现在运行良好,感谢所有阅读我的问题的人。