Raz*_*zon 1 android dao viewmodel android-room android-livedata
我试图使用LiveData和viewmodel从房间中获取自定义对象数据的列表。使用Livedata的getValue()方法时,返回null,但获取列表直接显示实际数据。如何在Viewmodel类中使用LiveData获得Period类的列表。
实体类
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
转换器类别
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;
}
}
Run Code Online (Sandbox Code Playgroud)
DAO类
@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();
}
Run Code Online (Sandbox Code Playgroud)
数据库
@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();
}
Run Code Online (Sandbox Code Playgroud)
在ViewModel类中获取数据方法
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();
}
Run Code Online (Sandbox Code Playgroud)
通常以同步方式Room处理查询,但将这些查询与查询一起使用会以异步方式执行,因此,当您调用此行时:LiveData
LiveData<List<Period>> periodList = MyApplication.getDatabase().dao().getAllPeriodList();
Run Code Online (Sandbox Code Playgroud)
,您实际上得到了一个空容器,该容器将在执行查询和完成查询后进行更新。因此,要获取查询结果,甚至首先要执行查询,必须观察返回的LiveData。
现在一般的情况是刚刚通过的LiveData是Room从提供视图模型到您的视图,然后观察LiveData在改变视图。
内部ViewModel:
public LiveData<List<Period>> getPeriods() {
return MyApplication.getDatabase().dao().getAllPeriodList();
}
Run Code Online (Sandbox Code Playgroud)
内部视图:
viewModel.getPeriods().observe(this, new Observer<List<Period>>() {
@Override
public void onChanged(@Nullable List<Period> periods) {
updateList(periods);
}
});
Run Code Online (Sandbox Code Playgroud)