Android 没有实时数据的房间

Android 没有实时数据的房间,android,android-room,android-livedata,Android,Android Room,Android Livedata,我正在试验Room数据库我不希望我的数据被观察,我只想从数据库中提取一次数据。如何使用MVVM实现这一点 我面临的问题是:如果我尝试在没有AsyncTask的情况下获取数据,它会给出: 无法访问主线程上的数据库,因为它可能会长时间(如预期)锁定UI,如果我使用AsyncTask,则方法在AsyncTask完成之前返回nullList Dao类: @Query("SELECT * FROM student_table where StudentName = :studentName")List&l

我正在试验
Room
数据库我不希望我的数据被观察,我只想从数据库中提取一次数据。如何使用MVVM实现这一点

我面临的问题是:如果我尝试在没有
AsyncTask
的情况下获取数据,它会给出: 无法访问主线程上的数据库,因为它可能会长时间(如预期)锁定UI,如果我使用
AsyncTask
,则方法在
AsyncTask
完成之前返回null
List

Dao类:

@Query("SELECT * FROM student_table where StudentName = :studentName")List<Student> getStudentWithSameName(String studentName);
@Query(“从student_表中选择*,其中StudentName=:StudentName”)列表getStudentWithSameName(字符串StudentName);
存储库:

public List<Student> getAllStudentWithSameName(String studentName) {
    new GetAllStudentWithSameNameAsyncTask(studentDao).execute(studentName);
    return studentsWithSameName;
}



private class GetAllStudentWithSameNameAsyncTask extends AsyncTask< String,Void, List<Student> > {

    StudentDao studentDao;

    public GetAllStudentWithSameNameAsyncTask(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    @Override
    protected List<Student> doInBackground(String... strings) {
        List<Student> students = studentDao.getStudentWithSameName(strings[0]);
        return students;
    }

    @Override
    protected void onPostExecute(List<Student> students) {
        studentsWithSameName = students;
        super.onPostExecute(students);
    }
}
公共列表getAllStudentWithSameName(字符串studentName){
新建GetAllStudentWithSameNameAsyncTask(studentDao).execute(studentName);
返回学生的姓名;
}
私有类GetAllStudentWithSameNameAsyncTask扩展了AsyncTask{
学生道学生道;
公共GetAllStudentWithAmenameAsyncTask(StudentDao StudentDao){
this.studentDao=studentDao;
}
@凌驾
受保护列表doInBackground(字符串…字符串){
List students=studentDao.getStudentWithSameName(字符串[0]);
留学生;
}
@凌驾
受保护的void onPostExecute(列出学生){
studentsWithSameName=学生;
super.onPostExecute(学生);
}
}
视图模型:

public List<Student> getStudentWithSameName(String studentName) {
    studentsWithSameName = studentRepository.getAllStudentWithSameName(studentName);
    return studentsWithSameName;
}
public List getStudentWithSameName(字符串studentName){
studentsWithSameName=studentRepository.getAllStudentWithSameName(studentName);
返回学生的姓名;
}
主要活动:

viewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
List<Student> students = viewModel.getStudentWithSameName("Bill");
viewModel=ViewModelProviders.of(this.get)(StudentViewModel.class);
List students=viewModel.getStudentWithSameName(“比尔”);
使用Kotlin:

要返回直接类型而不是LiveData,请将
YourClassDao.kt
文件更改为对该方法使用
suspend
函数,并将返回类型从
LiveData
更改为仅
SOMETHING
。(您还需要更改任何调用该方法的函数,但这些函数很容易找到,因为在您修复它之前,它不会编译。)因为它是,所以您需要以不同的方式调用它


在我的
YourClassDao.kt
中:

//这将返回一个LiveData对象
@查询(“从my_表中选择*,其中my_字段=:myId”)
趣味getMyObject(myId:String):LiveData
变成:

//这将返回一个普通对象
@查询(“从my_表中选择*,其中my_字段=:myId”)
挂起getMyObject(myId:String):列表
在我的例子中,我使用如下函数:

//使用上面的第二个(suspend-fun)版本
fun useMyData(){
val database=AppDatabase.getInstance(context).YourClassDao()//例如,上下文可以是一个活动。
val getDataJob=GlobalScope.async{database.getMyObject(“someId”)}
getDataJob.invokeOnCompletion{cause->
如果(原因!=null){
//发生了一些事情,工作没有成功完成。请在这里处理
单位
}否则{
val myData=getDataJob.getCompleted()
//项目1
// ***************************
//对你的数据做点什么
// ***************************
单位//这只是因为这里的lambda必须返回单位
}
}
//项目2
}

请记住,这仍然适用于异步数据,因此我的代码中的
项目2
可能发生在
项目1
之前

请在如何检索列表中显示代码:)也许他发现了这个。。。嗯,是的,不要在UI线程上获取数据,这可能会导致ANR。@Brandon为了更好地理解,我添加了代码片段。谢谢@Faisal,它成功了!这正是我想要的。不推荐使用GlobalScope吗?