realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.46k stars 1.75k forks source link

RealmObject.asObservable() throws IllegalStateException when use Schedulers.io() #2607

Closed ghost closed 8 years ago

ghost commented 8 years ago

I tried to add RealmObject item to Realm and wrap this operation into Observable. This is my code

return Observable.defer(new Func0<Observable<T>>() {
            @Override
            public Observable<T> call() {
                Log.d("TEST", Thread.currentThread().getName());
                final Realm mRealm = Realm.getDefaultInstance();
                mRealm.beginTransaction();
                Observable<T> result = mRealm.copyToRealmOrUpdate(item)
                        .<T>asObservable()
                        .map(new Func1<RealmObject, T>() {
                            @Override
                            public T call(RealmObject realmObject) {
                                Log.d("TEST", Thread.currentThread().getName());
                                return (T) mRealm.copyFromRealm(realmObject);
                            }
                        })
                        .observeOn(AndroidSchedulers.mainThread());
                mRealm.commitTransaction();
                return result;
            }
        });

And use this as

rep.addOrUpdate(mUser)
                .subscribeOn(Schedulers.io())
                .subscribe(new Action1<User>() {
                    @Override
                    public void call(final User user) {
                        Log.d("TEST", Thread.currentThread().getName());
                    }
                });

Tried all available schedulers.

When I try to run it I receive IllegalStateException: You can't register a listener from a non-Looper thread .

cmelchior commented 8 years ago

Hi @ramanbranavitski That is an expected error as your RealmResults is created on the Schedulers.io() thread and then accessed on the UI thread. It is also described here: https://github.com/realm/realm-java/blob/master/examples/rxJavaExample/src/main/java/io/realm/examples/rxjava/gotchas/GotchasActivity.java#L94-Lundefined

I was just going over documentation, and it could be better explained there, so we will fix that.

ghost commented 8 years ago

Hi @cmelchior , I call

 .map(new Func1<RealmObject, T>() {
                            @Override
                            public T call(RealmObject realmObject) {
                                Log.d("TEST", Thread.currentThread().getName());
                                return (T) mRealm.copyFromRealm(realmObject);
                            }
                        })

According to documentation Realm.copyFromRealm() which makes it possible to copy Realm data into normal Java objects, effectively detaching them from Realm. And this also perform on Schedulers.io().

This exception is throw by your `addChangeListener method

if (realm.handler == null) {
            throw new IllegalStateException("You can't register a listener from a non-Looper thread ");
        }