RxJava onNext中的域事务冻结应用程序

时间:2016-07-24 13:57:38

标签: android performance realm rx-java

设置

我使用Retrofit从REST API检索数据。我使用RxJava的Observable而不是Retrofit通常的反应。在 .tt-suggestion span { display: : inline-block; float: right; } 回调方法中,我告诉视图在地图上显示我通过API收到的每个项目的标记。另外,我想将每个条目保存到Realm数据库。

问题

保存到数据库工作。但是,它会阻止UI很长一段时间,有时会导致最多1000个跳帧。没有Realm部分,显示所有标记 - 尽管一次超过3000个(我出于性能和可用性原因将它们聚类)只需要几分之一秒。但是,有了它,该应用程序似乎冻结了几秒钟。

保存到数据库工作,但Realm将填充所有条目。但这太慢了。

实施

(我在将代码粘贴之前做了一些重命名和缩短代码,以显示我认为可能存在问题的部分。)

MapsPresenter.java

onNext(Object obj)

RealmController.java

class MapsPresenter implements Presenter<MapsView> {

    private MapsView mapsView;

    private Subscription subscription;

    private MyApiClient apiClient;
    private Realm realm;

    MapsPresenter() {
        apiClient = MyApp.getMyApiClient();
        realm = RealmController.with(MyApp.getInstance()).getRealm();
    }


    void loadRetailers(...) {
        if (subscription != null && !subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }

        mapsView.showProgressIndicator();

        subscription = apiClient.retailers()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .flatMap(new Func1<Retailers, Observable<Retailer>>() {
                @Override
                public Observable<Dealer> call(Retailers retailers) {
                    return Observable.from(retailers.retailerList);
                }
            })
            .subscribe(new Subscriber<Dealer>() {
                @Override
                public void onCompleted() {
                    ...
                }

                @Override
                public void onError(Throwable e) {
                    ...
                }

                @Override
                public void onNext(Retailer retailer) {
                    realm.beginTransaction();
                    realm.insertOrUpdate(retailer);
                    realm.commitTransaction();
                }
            });
        }
    }
}

问题

即使API调用后有几百个操作,如何提高插入/更新Realm条目的速度?我有什么东西可以忽略吗?

1 个答案:

答案 0 :(得分:2)

首先,真的很喜欢你构建问题的方式。

  1. 您的flatMap代码应该高于您的subscribeOn,以使其在observeOn中给出的Scheduler上运行。现在,代码正在MainThread上运行。

  2. 你正在MainThread上做Realm写操作,这很好,但是你没有使用Realm给出的Aync方法,尝试在executeTransactionAsync块中执行write操作。

  3. 此问题与您遇到的问题无关,但可以改进您在Presenter中处理订阅的方式。

  4. 示例示例如下,

    public void fetchGitHubUsersFromRetrofit() {
      internetConnection.isInternetOn(context)
        .filter(connectionStatus -> connectionStatus)
        .switchMap(connectionStatus -> gitHubApiInterface.getGitHubUsersList())
        .subscribeOn(rxSchedulerConfiguration.getComputationThread())
        .observeOn(rxSchedulerConfiguration.getMainThread())
        .map(gitHubUserList -> {
          realm.executeTransactionAsync(realm -> realm.copyToRealmOrUpdate(gitHubUserList));
        });
    }
    

    如果您正在寻找详细的代码参考,请查看此https://github.com/viraj49/Realm_android-injection-rx-test