У меня есть метод вставки базы данных постоянный номер, который выглядит следующим образом:
@Dao
public interface CountriesDao{
@Insert(onConflict = REPLACE)
List<Long> addCountries(List<CountryModel> countryModel);
}
Я понимаю, что это не может быть запущено в главном потоке. Вот как я определяю свою базу данных:
Room.inMemoryDatabaseBuilder(context.getApplicationContext(), MyDatabase.class).build();
Я пытаюсь использовать rxjava2, чтобы не запускаться в главном потоке. Я создал следующий метод:
public void storeCountries(List<CountryModel> countriesList) {
Observable.just(db.countriesDao().addCountries(countriesList))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DefaultSubscriber<List<Long>>(){
@Override
public void onSubscribe(@NonNull Disposable d) {
super.onSubscribe(d);
}
@Override
public void onNext(@NonNull List<Long> longs) {
super.onNext(longs);
Timber.d("insert countries transaction complete");
}
@Override
public void onError(@NonNull Throwable e) {
super.onError(e);
Timber.d("error storing countries in db"+e);
}
@Override
public void onComplete() {
Timber.d("insert countries transaction complete");
}
});
}
Для меня это явно сейчас работает в другой теме. НЕ основной поток, но когда я запускаю этот код, я получаю следующую ошибку:
Полная трассировка стека приведена ниже. Почему это происходит?
Процесс: com.mobile.myapp.staging, PID: 12990
java.lang.IllegalStateException: фатальное исключение, генерируемое в планировщике. Вызвано: java.lang.IllegalStateException: Не удается получить доступ к базе данных на основной поток, так как он может потенциально заблокировать пользовательский интерфейс на длительный период времени. в io.reactivex.android.schedulers.HandlerScheduler $ ScheduledRunnable.run(HandlerScheduler.java:111) на android.os.Handler.handleCallback(Handler.java:751) на android.os.Handler.dispatchMessage(Handler.java:95) на android.os.Looper.loop(Looper.java:154) на android.app.ActivityThread.main(ActivityThread.java:6077) в java.lang.reflect.Method.invoke (родной метод) в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:866) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) Вызвано: java.lang.IllegalStateException: Не удается получить доступ к базе данных на основной поток, так как он может потенциально заблокировать пользовательский интерфейс на длительный период времени. в android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:138) в android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:185) в com.mobile.myapp.data.room.dao.CountriesDao_Impl.addCountries(CountriesDao_Impl.java:165) в com.mobile.myapp.data.repositories.CountryRepository.storeCountries(CountryRepository.java:42) в com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter.cacheCountries(SignUpPresenter.java:40) в com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter $ CountriesSubscriber.onNext(SignUpPresenter.java:60) в com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter $ CountriesSubscriber.onNext(SignUpPresenter.java:49) в io.reactivex.internal.operators.observable.ObservableObserveOn $ ObserveOnObserver.drainNormal(ObservableObserveOn.java:200) в io.reactivex.internal.operators.observable.ObservableObserveOn $ ObserveOnObserver.run(ObservableObserveOn.java:252) в io.reactivex.android.schedulers.HandlerScheduler $ ScheduledRunnable.run(HandlerScheduler.java:109) на android.os.Handler.handleCallback(Handler.java:751) на android.os.Handler.dispatchMessage(Handler.java:95) на android.os.Looper.loop(Looper.java:154) на android.app.ActivityThread.main(ActivityThread.java:6077) в java.lang.reflect.Method.invoke (родной метод) в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:866) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Не важно, но если вам нужно знать, как выглядит класс defaultSubscriber, то он здесь:
DefaultSubscriber.java
public class DefaultSubscriber<T> implements Observer<T> {
Disposable disposable;
@Override
public void onSubscribe(@NonNull Disposable d) {
disposable = d;
}
@Override
public void onNext(@NonNull T t) {
}
@Override
public void onError(@NonNull Throwable e) {
Timber.e(e);
}
@Override
public void onComplete() {
}
public void unsubscribe(){
if(disposable!=null && !disposable.isDisposed()){
disposable.dispose();
}
}
}