我正在使用干净的体系结构构建应用程序。 从ViewModel调用用例需要在Room Database上运行查询时出现错误,告诉我在主线程中访问它。
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()
}
我的存储库方法实现
override fun getPatient(): Single<Patient> {
val patientDataStore = PatientDataStoreFactory().create()
return patientDataStore.patient()
}
这是在运行db.patientDAO()。getAllPatients()。isNotEmpty()时在My PatientDataStoreFactory中发生崩溃的地方
@Singleton
class PatientDataStoreFactory {
private val db = DaggerWrapper.getInstance().database()
fun create(): PatientDataStore {
return if (db.patientDAO().getAllPatients().isNotEmpty()){
LocalPatientDataStore()
} else {
CloudPatientDataStore()
}
}
}
在我的ViewModel中,我正在订阅用例执行,所以我不理解此崩溃... 有什么想法吗?
答案 0 :(得分:2)
问题在这里:db.patientDAO().getAllPatients()
。您正在UI线程上调用getAllPatients()
。您应该包裹在Single
中并订阅Schedulers.io()
。
一种可能的解决方案是重写以下代码:
val patientDataStore = PatientDataStoreFactory().create()
return patientDataStore.patient()
像这样:
return Single.fromCallable { PatientDataStoreFactory().create() }
.flatMap { store -> store.patient() }