Realm access from incorrect thread in rx and dagge

2019-08-16 07:43发布

I know this question asks a lot but i am confused by reading this question.In my project i am using dagger, rx and realm in mvp pattern.I have an application with a LoginActivity that when the user login correctly, the user information that comes from server store in realm in this page and user jumps to MainActivity.In MainActivity i want this user info but i got this error:

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

I know that :

Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

In my Appliction class i have initialized DaggerAplicationComponnet.I have applicationModule:

@AppScope
@Component(modules = {ApplicationModule.class, NetworkModule.class , AppRealmModule.class})
public interface ApplicationComponent {
    Realm getRealm();
    ...
}

and AppRealmModule:

@Module
public class AppRealmModule {

    @Provides
    @AppScope
    Realm provideRealm (Context context) {
        Realm.init(context);
        RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
                .deleteRealmIfMigrationNeeded()
                .name("Payeshdb")
                .build();
        Realm.setDefaultConfiguration(realmConfiguration);
        return Realm.getDefaultInstance();
    }

That means , i create realm instance on ui thread.Now in MainActivity i have read realm:

@Override
public Observable<User> findUser() {
    return Observable.create(new ObservableOnSubscribe<User>() {
        @Override
        public void subscribe(ObservableEmitter<User> emitter) throws Exception {
            try {
                User user = realm.where(User.class).findFirst();
                User user1 = realm.copyFromRealm(user);
                emitter.onNext(user1);
                emitter.onComplete();

            }catch (Exception e) {
                emitter.onError(e);
            }
        }
    });
}

Now, in presenter i am using rx in this way:

userRepository.findUser()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<User>() {
                    @Override
                    public void onNext(User user) {

                    }

                    @Override
                    public void onError(Throwable e) {
                      // got error: Realm access from incorrect thread.
                    }

                    @Override
                    public void onComplete() {

                    }
                });

this is a place that i got above error. In some post i have read this:

Use copyFromRealm to get the data from realm which will return them as plain objects rather than realm objects.

And i do that but i still got error.

Is it possible initialize realm with dagger and use different thread for crud operation?

What is your suggestion?

2条回答
Bombasti
2楼-- · 2019-08-16 08:12
@Override
public Observable<User> findUser() {
  return Observable.create(new ObservableOnSubscribe<User>() {
    @Override
    public void subscribe(ObservableEmitter<User> emitter) throws Exception {
        try(Realm realm = Realm.getDefaultInstance()) {
            realm.refresh();
            User user = realm.where(User.class).findFirst();
            User user1 = realm.copyFromRealm(user);
            emitter.onNext(user1);
            emitter.onComplete();
        } catch (Exception e) {
            emitter.onError(e);
        }
    }
  });
}
查看更多
手持菜刀,她持情操
3楼-- · 2019-08-16 08:12

As the error says

Realm objects can only be accessed on the thread they were created

So just subscribe on the same thread you created Realm

userRepository.findUser()
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(AndroidSchedulers.mainThread())
查看更多
登录 后发表回答