Android 房间数据库 RxAndroid,异常:java.lang.IllegalStateException:无法在主线程上访问数据库,因为
Android Room database RxAndroid, Exception : java.lang.IllegalStateException: Cannot access database on the main thread since
目前,我正在使用 RxAndroid 和 Retrofit 从 Web API 获取数据,并想将该数据存储在 Room 数据库中,但出现异常
当我搜索并发现,房间数据库操作在 UI 线程上不起作用,所以我在 RXAndroid 中添加了 .subscribeOn(Schedulers.io())
仍然在抛出
java.lang.IllegalStateException: Cannot access the database on the main thread since it may potentially lock the UI for a long period of time.
public void onClickLogin(View view) {
io.reactivex.Observable
.zip(getLogin(Constants.EMAILID, Constants.PASSWORD),
getUserInfo(Constants.EMAILID, Constants.PASSWORD),
getProductDetails(Constants.EMAILID, Constants.PASSWORD).subscribeOn(Schedulers.io()),
.observeOn(AndroidSchedulers.mainThread())
new Function3<List<LoginModule>,
List<UserInfoModule>, ProductModule, AllZipData>() {
@Override
public AllZipData apply(List<LoginModule> loginModuleList, List<UserInfoModule> useerInfoModules, ProductModule productModule) throws Exception {
AllZipData allZipData = new AllZipData();
allZipData.setLoginModuleList(loginModuleList);
allZipData.setUserInfoModuleList(UserInfoModule);
allZipData.setProductModule(productModule);
return allZipData;
}
}).subscribe(new Observer<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
MyDatabase MyDatabase = MyDatabase.getInstance(context);
for (int i = 0; i < allZipData.getUserInfoModuleList().size(); i++) {
UserInfoTable userInfoTable = new UserInfoTable();
userInfoTable.setValue1(allZipData.getUserInfoModuleList().get(i).getValue1());
userDatabase.userDao().insertUserInfo(userInfoTable);
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: all zip data " + e.toString());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: all data zipped");
}
});
}
如何使用RxAndroid解决这个异常。
如何添加retryWhen();?
我相信这条线还需要一些 RxJava
操作:
userDatabase.userDao().insertUserInfo(userInfoTable);
我相信你的 dao 中的 insertUserInfo
应该 return 一个 Completable
。
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
清楚地表明您在 MainThread
上 运行 您的应用程序,这会导致屏幕冻结。您应该在应用程序的后台线程上处理您的查询或长时间的 运行 操作。
改变这个
observeOn(AndroidSchedulers.mainThread())
到
observeOn(Schedulers.io())
这个异常发生在哪里?如果它在 onNext
中,那是因为您指定了 observeOn(mainThread())
,因此数据库访问发生在主线程上。
试试这个
Observable.zip(
getLogin(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()), // <--------------------------------
getUserInfo(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()), // <--------------------------------
getProductDetails(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()) // <--------------------------------
)
.observeOn(Schedulers.io()) // <--------------------------------
.doOnNext(allZipData -> {
MyDatabase MyDatabase = MyDatabase.getInstance(context);
for (int i = 0; i < allZipData.getUserInfoModuleList().size(); i++) {
UserInfoTable userInfoTable = new UserInfoTable();
userInfoTable.setValue1(
allZipData.getUserInfoModuleList().get(i).getValue1()
);
userDatabase.userDao().insertUserInfo(userInfoTable);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
// notify UI here?
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: all zip data " + e.toString());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: all data zipped");
}
});
使用Map进行运算。检查这个
.subscribeOn(Schedulers.io())
.map {
}
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
}
.subscribeWith(new DisposableObserver<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
}
@Override
public void onError(Throwable throwable) {
}
})
目前,我正在使用 RxAndroid 和 Retrofit 从 Web API 获取数据,并想将该数据存储在 Room 数据库中,但出现异常
当我搜索并发现,房间数据库操作在 UI 线程上不起作用,所以我在 RXAndroid 中添加了 .subscribeOn(Schedulers.io())
仍然在抛出
java.lang.IllegalStateException: Cannot access the database on the main thread since it may potentially lock the UI for a long period of time.
public void onClickLogin(View view) {
io.reactivex.Observable
.zip(getLogin(Constants.EMAILID, Constants.PASSWORD),
getUserInfo(Constants.EMAILID, Constants.PASSWORD),
getProductDetails(Constants.EMAILID, Constants.PASSWORD).subscribeOn(Schedulers.io()),
.observeOn(AndroidSchedulers.mainThread())
new Function3<List<LoginModule>,
List<UserInfoModule>, ProductModule, AllZipData>() {
@Override
public AllZipData apply(List<LoginModule> loginModuleList, List<UserInfoModule> useerInfoModules, ProductModule productModule) throws Exception {
AllZipData allZipData = new AllZipData();
allZipData.setLoginModuleList(loginModuleList);
allZipData.setUserInfoModuleList(UserInfoModule);
allZipData.setProductModule(productModule);
return allZipData;
}
}).subscribe(new Observer<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
MyDatabase MyDatabase = MyDatabase.getInstance(context);
for (int i = 0; i < allZipData.getUserInfoModuleList().size(); i++) {
UserInfoTable userInfoTable = new UserInfoTable();
userInfoTable.setValue1(allZipData.getUserInfoModuleList().get(i).getValue1());
userDatabase.userDao().insertUserInfo(userInfoTable);
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: all zip data " + e.toString());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: all data zipped");
}
});
}
如何使用RxAndroid解决这个异常。
如何添加retryWhen();?
我相信这条线还需要一些 RxJava
操作:
userDatabase.userDao().insertUserInfo(userInfoTable);
我相信你的 dao 中的 insertUserInfo
应该 return 一个 Completable
。
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
清楚地表明您在 MainThread
上 运行 您的应用程序,这会导致屏幕冻结。您应该在应用程序的后台线程上处理您的查询或长时间的 运行 操作。
改变这个
observeOn(AndroidSchedulers.mainThread())
到
observeOn(Schedulers.io())
这个异常发生在哪里?如果它在 onNext
中,那是因为您指定了 observeOn(mainThread())
,因此数据库访问发生在主线程上。
试试这个
Observable.zip(
getLogin(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()), // <--------------------------------
getUserInfo(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()), // <--------------------------------
getProductDetails(Constants.EMAILID, Constants.PASSWORD)
.subscribeOn(Schedulers.io()) // <--------------------------------
)
.observeOn(Schedulers.io()) // <--------------------------------
.doOnNext(allZipData -> {
MyDatabase MyDatabase = MyDatabase.getInstance(context);
for (int i = 0; i < allZipData.getUserInfoModuleList().size(); i++) {
UserInfoTable userInfoTable = new UserInfoTable();
userInfoTable.setValue1(
allZipData.getUserInfoModuleList().get(i).getValue1()
);
userDatabase.userDao().insertUserInfo(userInfoTable);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
// notify UI here?
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: all zip data " + e.toString());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: all data zipped");
}
});
使用Map进行运算。检查这个
.subscribeOn(Schedulers.io())
.map {
}
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
}
.subscribeWith(new DisposableObserver<AllZipData>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(AllZipData allZipData) {
}
@Override
public void onError(Throwable throwable) {
}
})