领域内部访问Rx Observable错误

时间:2016-03-15 16:20:25

标签: android rx-java realm

当我尝试在realm实例上进行操作时,我遇到错误,如下所示:

.flatMap(h -> Observable.from(h.getEntityDataList())).filter(p -> p.isMyProfile())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<ProfileView>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    Log.v("test", "error: " + e.toString());
                }

                @Override
                public void onNext(ProfileView profileView) {                        
                    realmManager.saveActiveUser(gson.toJson(profileView));
                   //...
                }
            });

RealmManager:

public class RealmManager{
    private Realm realm;

    public RealmManager(){
        realm = Realm.getDefaultInstance();
    }

    public void saveActiveUser(String json)}{
        realm...
    } 

代码进入onError()以上显示realm objects can only be accessed on the thread they were created。我正在使用Dagger将RealmManager注入第一个代码中。

如何克服这个?制作RealmManager类的最佳实践是什么?我应该使RealmManager单例(和领域对象静态)并在任何地方访问它吗?我应该像上面那样制作并随时注入吗?

编辑:我正在注入Application Manager中提供的RealmManager实例,该实例是Singleton。

1 个答案:

答案 0 :(得分:2)

由于Realm对象是活动对象,因此无法在一个线程(IO线程)上获取它并在另一个线程(主线程)中使用它。您可以使用下一个代码(从Realm的文档中获取)来分离这些对象:

realm.where(Person.class).findFirst().<Person>asObservable()
    .map(new Func1<Person, Person>() {
        @Override
        public Person call(Person person) {
            // Convert live object to a static copy
            return realm.copyFromRealm(person);
        }
    })
    .buffer(2)
    .subscribe(new Action1<List<Person>>() {
        @Override
        public void call(List<Person> persons) {
            // Without `map` and `copyFromRealm`, v1 and v2 would be the same
            Person v1 = persons.get(0);
            Person v2 = persons.get(1);
        }
    });

使用Realm with Dagger并不是我想要的那么顺利。

你不应该忘记关闭Realm。否则,您的应用程序将更有可能被系统杀死(如果资源不足)。

Realm.getInstance()为每个线程创建实例。而且你不能在一个线程中创建Realm并在另一个线程中使用它。

我认为最好的选择是使用DI的范围。但作为一种快速解决方案,您可以尝试在匕首模块中构建Provider<Realm> realmProvider