【发布时间】:2016-08-01 18:46:10
【问题描述】:
我在 Android 上使用 Clean Code Architecture 和 Dagger with Realm,但我找不到让它一起工作的方法。 底线是,我总是得到:
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
@Override
public Observable<List<Item>> fetchAllItems() {
final List<Item> items = new ArrayList<>();
final Realm realm = Realm.getInstance(new RealmConfiguration.Builder(context).build());
final RealmQuery<Checkboxes> queryCheck = realm.where(Checkboxes.class);
final RealmQuery<ImageItem> queryImage = realm.where(ImageItem.class);
return queryCheck.findAll()
.asObservable()
.flatMap(new Func1<RealmResults<Checkboxes>, Observable<RealmResults<ImageItem>>>() {
@Override
public Observable<RealmResults<ImageItem>> call(RealmResults<Checkboxes> checkboxes) {
for (Checkboxes checks : checkboxes)
items.add(checks);
return queryImage.findAll().asObservable();
}
})
.flatMap(new Func1<RealmResults<ImageItem>, Observable<List<Item>>>() {
@Override
public Observable<List<Item>> call(RealmResults<ImageItem> imageItems) {
for (ImageItem images : imageItems)
items.add(images);
return Observable.create(new Observable.OnSubscribe<List<Item>>() {
@Override
public void call(Subscriber<? super List<Item>> subscriber) {
subscriber.onNext(items);
}
});
}
});
}
public class GetItemsUseCase extends UseCase {
private final ItemsRepository itemsRepository;
@Inject
public GetItemsUseCase(ItemsRepository itemsRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) {
super(threadExecutor, postExecutionThread);
this.itemsRepository = itemsRepository;
}
@Override
protected Observable buildUseCaseObservable() {
return this.itemsRepository.fetchAllItems();
}
}
还有UseCase:
public void execute(Subscriber UseCaseSubscriber) {
this.subscription = this.buildUseCaseObservable()
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.getScheduler())
.subscribe(UseCaseSubscriber);
}
我不确定是否有任何方法可以让 Realm 使用这种模式。 整个项目在我的GitHub上开源:https://github.com/leonardo2204/materialnotes/tree/bug_thread_realm
编辑:
Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
at io.realm.BaseRealm.checkIfValid(BaseRealm.java:456)
at io.realm.RealmResults.addChangeListener(RealmResults.java:926)
at io.realm.rx.RealmObservableFactory$5.call(RealmObservableFactory.java:147)
at io.realm.rx.RealmObservableFactory$5.call(RealmObservableFactory.java:131)
at rx.Observable.unsafeSubscribe(Observable.java:9860)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:9860)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:9860)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
【问题讨论】:
-
使用领域,每个线程都需要自己的领域实例。您不能将领域实例或对象从线程传递到线程。还要确保在退出线程时关闭领域实例。
-
所以问题可能是我正在获取线程中的对象(来自 ThreadPoolExecutor)并将其发送到 UI 线程?
-
现在你可以弄清楚如何解决这个问题。 :)
标签: java android realm rx-java dagger-2