优化改造请求以防止滞后

Optimizing Retrofit Request To Prevent Lagging

当用户登录到我的应用程序时,我会进行大量轮询。目前,我们没有太多 payload。但是,有效负载 目前每天增长 100 个。这使我们每个用户拥有大约 300 条记录。这是第一周。因此,我们开始 优化 接下来的 API修改的很好,但是Android应用不稳定

我有一个请求,其中用户目前最多有两个 Territories,我需要获取每个中的所有 Items 领土。所以,我这样做了:

/**
* This is to get all user territories and for each and every territory, fetch all items there;
*/
private Observable<ItemListResponse> getAlltemIByTerritory() {

    List<String> territories = PrefUtils.getUserTerritories(context);
    return Observable.from(territories).flatMap(territory -> fetchAllTerritoryItemPaged(territory, 1));
}

/**
* This is to fetch all items in a passed territory. There's a per_page of 21.
*/
private Observable<ItemListResponse> fetchAllTerritoryItemPaged(String territory, int page) {
    Log.e(TAG, "Each territory page: " + page);

    return itemAPI.getIems("Bearer " + PrefUtils.getToken(context), page, 21, territory)
            .flatMap(itemListResponse -> {
                Meta meta = itemListResponse.getBakeResponse().getMeta();
                Observable<ItemListResponse> thisPage = Observable.just(itemListResponse);
                if (meta.getPage() != meta.getPageCount() && meta.getPageCount() > 0) {
                    Observable<ItemListResponse> nextPage = fetchAllTerritoryItemPaged(territory, page + 1);

                    return thisPage.concatWith(nextPage);
                } else {
                    return thisPage;
                }
            });
}

利用 Observable

public void getAlltemIByTerritory(APIRequestListener apiRequestListener) {
    realm.executeTransaction(realm1 -> realm1.where(RealmItem.class).findAll().deleteAllFromRealm());

    getAlltemIByTerritory()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<ItemListResponse>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG, "Completed Item");
                    apiRequestListener.didComplete(WhichSync.ITEM);
                    unsubscribe();
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                    handleError(e, apiRequestListener, WhichSync.ITEM);
                    unsubscribe();
                }

                @Override
                public void onNext(ItemListResponse itemListResponse) {
                    Log.e(TAG, "In the handler next " + itemListResponse.toString());
                    realm.executeTransaction(realm1 -> {
                        for (Item itemData : itemListResponse.getItemResponse().getData()) {
                            RealmItem realmItem = realm1.where(RealmItem.class).equalTo("id", itemData.getId()).findFirst();
                            if (realmItem != null)
                                realmItem.deleteFromRealm();

                            realm1.copyToRealm(Item.copyBakeryToRealm(itemData));
                        }
                    });

                    apiRequestListener.onProgress(itemListResponse.getItemResponse().getMeta(), itemListResponse.getItemResponse().getData().size(), WhichSync.ITEM);
                }
            });
}

Log.e(TAG, "Each territory page: " + page); 这一行和这一行 Log.e(TAG, "In the handler next " + itemListResponse.toString()); 对于 1780 条记录读为 23。有 21 条记录 per_page。然后,第二行停止显示。然后,视图已挂起。然后,当第一个完成后,我会看到第二个随即吐出日志。

这很好用,只是当记录超过 700 条时(第一次尝试使用 1780 条记录),UI 有很大的延迟。在大多数 pre-lollipops 上,它会与 NoClassDefined Exception 一起崩溃,但有时它会起作用。但是,延迟仍然存在。

任何关于优化代码的帮助,谢谢。

Tail Recursion 这里:

/**
* This is to fetch all items in a passed territory. There's a per_page of 21.
*/
private Observable<ItemListResponse> fetchAllTerritoryItemPaged(String territory, int page) {
    Log.e(TAG, "Each territory page: " + page);

    return itemAPI.getIems("Bearer " + PrefUtils.getToken(context), page, 21, territory)
            .flatMap(itemListResponse -> {
                Meta meta = itemListResponse.getItemResponse().getMeta();
                Observable<ItemListResponse> thisPage = Observable.just(itemListResponse);
                if (meta.getPage() != meta.getPageCount() && meta.getPageCount() > 0) {
                    Observable<ItemListResponse> nextPage = fetchAllTerritoryItemPaged(territory, page + 1);

                    return thisPage.concatWith(nextPage);
                } else {
                    return thisPage;
                }
            });
}

是导致问题的原因。幸运的是,Rx 为我们提供了 BehaviorSubject.

所以,我做了类似的事情

private Observable<ItemListResponse> fetchAllTerritoryItemPaged(String territory, int page) {

    BehaviorSubject<Integer> pageControl = BehaviorSubject.create(page);
    Observable<ItemListResponse> ret = pageControl.asObservable().concatMap(integer -> {

        if (integer > 0) {

            return itemAPI.getIems("Bearer " + PrefUtils.getToken(context), integer, 21, territory)
                    .doOnNext(itemListResponse -> {
                        Meta meta = itemListResponse.getItemResponse().getMeta();
                        if (meta.getPage() != meta.getPageCount() && meta.getPageCount() > 0) {
                            pageControl.onNext(integer + 1);
                        } else {
                            pageControl.onNext(-1);
                        }
                    });
        } else {
            return Observable.<ItemListResponse>empty().doOnCompleted(pageControl::onCompleted);
        }
    });

    return Observable.defer(() -> ret);
}

这不仅消除了延迟,而且请求进来的速度也非常快