切换Realm对象从Main到Background线程

时间:2018-03-20 15:00:14

标签: java android multithreading realm rx-java2

我使用原始的Realm包装器来实现RxJava。这样:

Flowable<RealmResult<RealmUser> result =
realm.where(RealmUser.class)
.findAllAsync()
.asFlowable();

数据加载到Realm Background线程上并发送到主线程。 我的问题是我需要将大量的Realm对象映射到自己的POJO(独立的业务层)。 Realm对象不能在线程之间传递。这意味着我必须在主线程上映射不合需要的对象并阻止主线程。你知道在后台线程上执行映射并使用类似的方法吗?是否有可能发出RealmResult的非托管副本(在后台线程上直接来自Realm)?我找不到类似的方式。

使用copyFromRealm不是一个好选择,因为结果与我的自定义映射相同。

此时我只使用我需要的attributech的用户使用新的模型类。结果是映射时间较短,但是在导致UI工件的主线程上。

由于

1 个答案:

答案 0 :(得分:1)

如果您不想微观管理您实际执行查询的后台循环线程的存在:

private Observable<List<User>> createResults() {
    return Observable.create((ObservableOnSubscribe<List<User>>) emitter -> {
        Realm realm = Realm.getDefaultInstance();
        final RealmResults<RealmUser> results = realm.where(RealmUser.class).findAllAsync();

        final RealmChangeListener<RealmResults<RealmUser>> realmChangeListener = element -> {
            if(element.isLoaded() && !emitter.isDisposed()) {
                List<User> users = mapFrom(element);
                if(!emitter.isDisposed()) {
                    emitter.onNext(users);
                }
            }
        };
        emitter.setDisposable(Disposables.fromAction(() -> {
            if(results.isValid()) {
                results.removeChangeListener(realmChangeListener);
            }
            realm.close();
        }));
        results.addChangeListener(realmChangeListener);
    }).subscribeOn(looperScheduler.getScheduler()).unsubscribeOn(looperScheduler.getScheduler());
}

然后,您可以执行以下快捷方式,但它会对您的查询进行两次评估:

Flowable<RealmResult<RealmUser> result =
    realm.where(RealmUser.class)
         .findAllAsync()
         .asFlowable()
         .subscribeOn(AndroidSchedulers.mainThread())
         .unsubscribeOn(AndroidSchedulers.mainThread())
         .filter(RealmResults::isLoaded)
         .observeOn(Schedulers.from(singleThreadedExecutor))
         .map((ignored) -> {
             RealmConfiguration configuration = realm.getConfiguration();
             try(Realm realm = Realm.getInstance(configuration)) {
                 RealmResults<RealmUser> results = realm.where(RealmUser.class).findAll();
                 return mapToUsersList(results);
             }
         })
         .observeOn(AndroidSchedulers.mainThread())
         .subscribe((users) -> { ...