Reputation: 133
Currently, I am fetching data from Web API using RxAndroid and Retrofit, and want to store that Data in Room database but getting an exception
As I search and found that, room database operations won't work on UI thread so I added .subscribeOn(Schedulers.io())
in RXAndroid
still it is throwing
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");
}
});
}
how to solve this exception using RxAndroid.
How to add retryWhen();?
Upvotes: 4
Views: 2197
Reputation: 7193
Use Map to perform operation. Check this
.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) {
}
})
Upvotes: 0
Reputation: 69997
Where does this exception happen? If it is in onNext
, that's because you specified observeOn(mainThread())
thus the database access happens on the main thread.
Try this
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");
}
});
Upvotes: 3
Reputation: 10214
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
Clearly says that you're running on MainThread
of your application, which leads to freezing of the screen. You should handle your queries or long running operations on background thread of your application.
Change this
observeOn(AndroidSchedulers.mainThread())
to
observeOn(Schedulers.io())
Upvotes: 0
Reputation: 8371
I believe this line still needs some RxJava
operations :
userDatabase.userDao().insertUserInfo(userInfoTable);
I believe the insertUserInfo
in your dao should return a Completable
.
Upvotes: 0