我有一个房间持久数据库插入方法,如下所示:
@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:无法访问主线程上的数据库,因为它可能会长时间锁定 UI。在 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:
不重要,但如果您需要知道 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();
}
}
}