Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用RxJava访问房间数据库时出错,带有用例和干净的架构_Android_Kotlin_Rx Java_Rx Java2_Clean Architecture - Fatal编程技术网

Android 使用RxJava访问房间数据库时出错,带有用例和干净的架构

Android 使用RxJava访问房间数据库时出错,带有用例和干净的架构,android,kotlin,rx-java,rx-java2,clean-architecture,Android,Kotlin,Rx Java,Rx Java2,Clean Architecture,我正在使用干净的架构构建一个应用程序。 当从我的ViewModel调用需要在我的房间数据库上运行查询的用例时,我遇到了一个错误,告诉我正在主线程中访问它 Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at android.arch.per

我正在使用干净的架构构建一个应用程序。 当从我的ViewModel调用需要在我的房间数据库上运行查询的用例时,我遇到了一个错误,告诉我正在主线程中访问它

Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:204)
    at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:232)
    at com.something.data.db.PatientDAO_Impl.getAllPatients(PatientDAO_Impl.java:229)
    at com.something.data.repositories.dataSource.PatientDataStoreFactory.create(PatientDataStoreFactory.kt:18)
    at com.something.data.repositories.PatientRepositoryImplementation.getPatient(PatientRepositoryImplementation.kt:97)
    at com.something.domain.useCases.GetPatientUseCase.execute(GetPatientUseCase.kt:10)
    at com.something.some_thing.searchForm.SearchFormViewModel.getPatientFromDb(SearchFormViewModel.kt:49)
    at com.something.some_thing.searchForm.SearchFormFragment.onCreateView(SearchFormFragment.kt:99)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
    at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
    at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
    at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
    at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
    at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
    at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
    at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
    at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1334)
    at android.app.Activity.performStart(Activity.java:7057)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2819)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2931) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1620) 
    at android.os.Handler.dispatchMessage(Handler.java:105) 
    at android.os.Looper.loop(Looper.java:173) 
    at android.app.ActivityThread.main(ActivityThread.java:6698) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782) 
这里有一些代码

我的ViewModel调用:

fun getPatient(){
    val disposable = getPatientUseCase.execute()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::getPatientSuccess, this::onError)
    compositeDisposable.add(disposable)
}
我的用例:

class GetPatientUseCase(private val patientRepository: PatientRepository){

fun execute(): Single<Patient> {
    return patientRepository.getPatient()
}
在我的ViewModel中,我订阅了用例执行,所以我不理解这个崩溃。。。
有什么想法吗?

问题在这里:
db.patientDAO().getAllPatients()
。您正在UI线程上调用
getAllPatients()
。您应该加入
单曲
并订阅
Schedulers.io()

可能的解决方案之一是重写以下代码:

val patientDataStore = PatientDataStoreFactory().create()
return patientDataStore.patient()
对这样的事情:

return Single.fromCallable { PatientDataStoreFactory().create() }
             .flatMap { store -> store.patient() }

问题就在这里:
db.patientDAO().getAllPatients()
。您正在UI线程上调用
getAllPatients()
。您应该加入
单曲
并订阅
Schedulers.io()

可能的解决方案之一是重写以下代码:

val patientDataStore = PatientDataStoreFactory().create()
return patientDataStore.patient()
对这样的事情:

return Single.fromCallable { PatientDataStoreFactory().create() }
             .flatMap { store -> store.patient() }

我打赌db.patientDAO().getAllPatients().isNotEmpty()当然它应该在堆栈跟踪中,而你没有provide@Selvin谢谢你的回答,是的,我没有上传整个stacktrace,但是我在代码示例之前提到了标签中发生错误的地方!好吧,我没有抱怨,因为我专注于代码。。。但是很明显,
db.patientDAO().getAllPatients()
是为了返回
List
而预先实现的,所以它:在主线程上访问数据库……嗯,但是我在订阅新线程的视图模型中执行用例,它不应该在主线程之外运行所有进程吗?编辑:添加的整个stacktraceroom也允许在主线程上执行您的查询,但您需要启用它。我打赌
db.patientDAO().getAllPatients().isNotEmpty()
当然它应该在堆栈跟踪中,而您没有provide@Selvin谢谢你的回答,是的,我没有上传整个stacktrace,但我在代码示例之前提到了标签中发生错误的地方!好吧,我没有抱怨,因为我专注于代码。。。但是很明显,
db.patientDAO().getAllPatients()
是为了返回
List
而预先实现的,所以它:在主线程上访问数据库……嗯,但是我在订阅新线程的视图模型中执行用例,它不应该在主线程之外运行所有进程吗?编辑:添加的整个stacktraceroom也允许在主线程上执行您的查询,但您需要启用它。感谢您的帮助,这无疑是一种使其工作的方法。但是为什么我要在主线程中调用getAllPatients?在第一个示例代码中,我正在执行我的用例并订阅Schedulers.io(),因此从此处开始运行的所有进程都应该在主线程之外执行,对吗?不,在io线程上不执行
getPatient()
。它在主线程上执行,但返回
Single
-并且此
Single
将在IO线程上订阅。感谢您的帮助,这无疑是使其工作的一种方式。但是为什么我要在主线程中调用getAllPatients?在第一个示例代码中,我正在执行我的用例并订阅Schedulers.io(),因此从此处开始运行的所有进程都应该在主线程之外执行,对吗?不,在io线程上不执行
getPatient()
。它在主线程上执行,但返回
Single
——该
Single
将在IO线程上订阅。