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) {

            }

        })