【问题标题】:Switch mapping Realm objects from Main to Background thread将映射领域对象从主线程切换到后台线程
【发布时间】:2018-03-20 15:00:14
【问题描述】:

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

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

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

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

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

谢谢

【问题讨论】:

  • 一个可能的选择是使用我创建的名为 Monarchy 的库,它将数据公开为 LiveData,观察后台线程上的查询更改,并允许在所述后台线程上进行映射。
  • 你为什么不直接切换到另一个带有 observeOn 的调度器并映射你的模型,然后你可以再次在主线程上使用它们
  • @elmorabea 请再次阅读我的问题。你恢复我需要的东西。 RealmResult 不能切换到不同的线程(从主线程到后台)。

标签: java android multithreading realm rx-java2


【解决方案1】:

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

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) -> { ...

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 2016-02-02
  • 1970-01-01
相关资源
最近更新 更多