房间数据库 Livedata getValue() returns null
Room database Livedata getValue() returns null
我试图使用 LiveData 和视图模型从房间中获取自定义对象数据列表。而使用Livedata的getValue()方法,returnsnull但是获取list直接显示的是实际数据。如何在视图模型 class.
中使用 LiveData 获取期间列表 class
Entity classes
@Entity
public class Period {
@PrimaryKey
@NonNull
String header;
@TypeConverters(WritterConverter.class)
ArrayList<Writter> writters;
public Period(String header, ArrayList<Writter> writters) {
this.header = header;
this.writters = writters;
}
public String getHeader() {
return header;
}
public ArrayList<Writter> getWritters() {
return writters;
}
}
@Entity
public class Writter {
String birth;
String death;
String name;
ArrayList<String> novels;
public Writter(){}
public Writter(String birth, String death, String name, ArrayList<String> novels) {
this.birth = birth;
this.death = death;
this.name = name;
this.novels = novels;
}
public String getBirth() {
return birth;
}
public String getDeath() {
return death;
}
public String getName() {
return name;
}
public ArrayList<String> getNovels() {
return novels;
}
}
Converter Class
public class WritterConverter {
@TypeConverter
public static ArrayList<Writter> fromString(String value){
Type listType = new TypeToken<ArrayList<Writter>>(){}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String fromArrayList(ArrayList<Writter> list){
Gson gson = new Gson();
String json = gson.toJson(list);
return json;
}
}
DAO class
@Dao
@TypeConverters({WritterConverter.class})
public interface DAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertPeriod(Period period);
@Query("SELECT * FROM Period WHERE header LIKE :header")
Period getPeriodList(String header);
@Query("SELECT * FROM Period")
LiveData<List<Period>> getAllPeriodList();
}
Database
@Database(version = 1, entities = {Period.class})
public abstract class MyDatabase extends RoomDatabase{
static MyDatabase databaseInstance;
public static MyDatabase getDatabaseInstance(Context context) {
if (databaseInstance == null)
databaseInstance = Room
.databaseBuilder(context, MyDatabase.class, "testDatabase1")
.fallbackToDestructiveMigration()
// .addMigrations(FROM_1_TO_2)
.build();
return databaseInstance;
}
abstract public DAO dao();
}
Get Data method in viewmodel class
private void getDataFromDatabase() {
new AsyncTask<Void, Void, LiveData<List<Period>>>() {
@Override
protected LiveData<List<Period>> doInBackground(Void... voids) {
LiveData<List<Period>> periodList = MyApplication.getDatabase().dao().getAllPeriodList();
// Period periodList = MyApplication.getDatabase().dao().getWriterList(EndPoints.THE_OLD_ENGLISH_PERIOD);
return periodList;
}
@Override
protected void onPostExecute(LiveData<List<Period>> aVoid) {
super.onPostExecute(aVoid);
// Period period = aVoid.getValue().get(0);
Log.d("header", aVoid.getValue().get(0).getHeader());
}
}.execute();
}
通常 Room
处理查询 同步 但与它一起使用 LiveData
这些查询在 ASynchronous 中执行方式,所以当您调用此行时:
LiveData<List<Period>> periodList = MyApplication.getDatabase().dao().getAllPeriodList();
,你实际上得到了一个 empty 容器,它将在执行并完成查询后得到 updated。因此,要获得查询结果,甚至要让查询首先得到 executed,您必须 observe 返回的 LiveData
.
现在通常的情况是 将 Room
从 ViewModel 提供的 LiveData
传递给您的 ViewModel View 然后观察 LiveData
在 View.
中的变化
内部 ViewModel:
public LiveData<List<Period>> getAllPeriods() {
return MyApplication.getDatabase().dao().getAllPeriodList();
}
里面查看:
viewModel.getAllPeriods().observe(this, new Observer<List<Period>>() {
@Override
public void onChanged(@Nullable List<Period> periods) {
updateList(periods);
}
});
事实是,
Asynctask
在后台的另一个线程上 运行 异步
Livedata
就像漂浮在数据库上以查看更改一样工作。
所以完成 Asyntask
的获取操作需要时间。您可以通过在 10 秒延迟的处理程序中测试 Asynctask
来查看它。
所以最好直接在view model中调用fetch操作,发送到activity/fragment as livedata.observe.
我试图使用 LiveData 和视图模型从房间中获取自定义对象数据列表。而使用Livedata的getValue()方法,returnsnull但是获取list直接显示的是实际数据。如何在视图模型 class.
中使用 LiveData 获取期间列表 classEntity classes
@Entity
public class Period {
@PrimaryKey
@NonNull
String header;
@TypeConverters(WritterConverter.class)
ArrayList<Writter> writters;
public Period(String header, ArrayList<Writter> writters) {
this.header = header;
this.writters = writters;
}
public String getHeader() {
return header;
}
public ArrayList<Writter> getWritters() {
return writters;
}
}
@Entity
public class Writter {
String birth;
String death;
String name;
ArrayList<String> novels;
public Writter(){}
public Writter(String birth, String death, String name, ArrayList<String> novels) {
this.birth = birth;
this.death = death;
this.name = name;
this.novels = novels;
}
public String getBirth() {
return birth;
}
public String getDeath() {
return death;
}
public String getName() {
return name;
}
public ArrayList<String> getNovels() {
return novels;
}
}
Converter Class
public class WritterConverter {
@TypeConverter
public static ArrayList<Writter> fromString(String value){
Type listType = new TypeToken<ArrayList<Writter>>(){}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String fromArrayList(ArrayList<Writter> list){
Gson gson = new Gson();
String json = gson.toJson(list);
return json;
}
}
DAO class
@Dao
@TypeConverters({WritterConverter.class})
public interface DAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertPeriod(Period period);
@Query("SELECT * FROM Period WHERE header LIKE :header")
Period getPeriodList(String header);
@Query("SELECT * FROM Period")
LiveData<List<Period>> getAllPeriodList();
}
Database
@Database(version = 1, entities = {Period.class})
public abstract class MyDatabase extends RoomDatabase{
static MyDatabase databaseInstance;
public static MyDatabase getDatabaseInstance(Context context) {
if (databaseInstance == null)
databaseInstance = Room
.databaseBuilder(context, MyDatabase.class, "testDatabase1")
.fallbackToDestructiveMigration()
// .addMigrations(FROM_1_TO_2)
.build();
return databaseInstance;
}
abstract public DAO dao();
}
Get Data method in viewmodel class
private void getDataFromDatabase() {
new AsyncTask<Void, Void, LiveData<List<Period>>>() {
@Override
protected LiveData<List<Period>> doInBackground(Void... voids) {
LiveData<List<Period>> periodList = MyApplication.getDatabase().dao().getAllPeriodList();
// Period periodList = MyApplication.getDatabase().dao().getWriterList(EndPoints.THE_OLD_ENGLISH_PERIOD);
return periodList;
}
@Override
protected void onPostExecute(LiveData<List<Period>> aVoid) {
super.onPostExecute(aVoid);
// Period period = aVoid.getValue().get(0);
Log.d("header", aVoid.getValue().get(0).getHeader());
}
}.execute();
}
通常 Room
处理查询 同步 但与它一起使用 LiveData
这些查询在 ASynchronous 中执行方式,所以当您调用此行时:
LiveData<List<Period>> periodList = MyApplication.getDatabase().dao().getAllPeriodList();
,你实际上得到了一个 empty 容器,它将在执行并完成查询后得到 updated。因此,要获得查询结果,甚至要让查询首先得到 executed,您必须 observe 返回的 LiveData
.
现在通常的情况是 将 Room
从 ViewModel 提供的 LiveData
传递给您的 ViewModel View 然后观察 LiveData
在 View.
内部 ViewModel:
public LiveData<List<Period>> getAllPeriods() {
return MyApplication.getDatabase().dao().getAllPeriodList();
}
里面查看:
viewModel.getAllPeriods().observe(this, new Observer<List<Period>>() {
@Override
public void onChanged(@Nullable List<Period> periods) {
updateList(periods);
}
});
事实是,
Asynctask
在后台的另一个线程上 运行 异步Livedata
就像漂浮在数据库上以查看更改一样工作。
所以完成 Asyntask
的获取操作需要时间。您可以通过在 10 秒延迟的处理程序中测试 Asynctask
来查看它。
所以最好直接在view model中调用fetch操作,发送到activity/fragment as livedata.observe.