【问题标题】:How to handle pagination in retrofit如何在改造中处理分页
【发布时间】:2014-07-29 04:20:23
【问题描述】:

我正在使用改造构建一个应用程序。一切正常,但我担心我的 API 请求的大小,并希望使用分页将它们分开。

使用 Retrofit 自动浏览 API 以默认下载所有可用数据的最佳策略是什么?

【问题讨论】:

    标签: android api-design retrofit okhttp


    【解决方案1】:

    首先,您使用的后端服务需要支持分页。其次,如果您希望获得一个示例,说明如何使用改造从客户端实现这一点,我建议您查看@JakeWharton 的u2020 项目。 GalleryService 改造接口以非常简单的方式实现了这种机制。这是接口本身的link

    这是一个基于 u2020 项目的轻量级示例

    // See how it uses a pagination index.
    public interface GalleryService {
      @GET("/gallery/{page}") //
      Gallery listGallery(@Path("page") int page);
    }
    

    通过跟踪已从您的 REST 服务下载的项目总量以及每页预定义的最大项目数,您可以计算调用您的 REST 服务以下载下一组项目所需的页面索引。

    然后你可以像这样调用你的rest api。

    int nextPage = totalItemsAlreadyDownloaded / ITEMS_PER_PAGE + 1;    
    restApi.listGallery(nextPage);
    

    这是一个基于 u2020 项目的非常简单的示例,但希望它能让您了解如何攻击它。

    【讨论】:

      【解决方案2】:

      所以我最终这样解决了我的问题:

      我在我的服务器上使用 Grape,所以我安装了 Grape-kaminari gem 来处理服务器端的分页。 Grape-kaminari 在您的 url 上提供页面查询,并在标题响应中添加方便的分页信息。

      我写了一个小类,让我可以自动递归浏览页面,直到我消耗完 API 上的所有数据:

      package com.farmgeek.agricountantdemo.app.helpers;
      
      import android.util.Log;
      
      import retrofit.client.Header;
      import retrofit.client.Response;
      
      public class APIHelper {
          public static PaginationData getPaginationData(Response response) {
              int currentPage = 1;
              int totalPages = 1;
              for (Header header : response.getHeaders()) {
                  try {
                          if (header.getName().equals("X-Page")) {
                              currentPage = Integer.parseInt(header.getValue());
                          } else if (header.getName().equals("X-Total-Pages")) {
                              totalPages = Integer.parseInt(header.getValue());
                          }
                  } catch (NullPointerException e) {
                      // We don't care about header items
                      // with empty names, so just skip over
                      // them.
                      Log.w("APIHelper -> getPaginationData", "Skipped over header: " + e.getLocalizedMessage());
                  }
              }
              return new PaginationData(currentPage, totalPages);
          }
      
          public static class PaginationData {
              public final int page;
              public final int total;
      
              public PaginationData(int currentPage, int totalPages) {
                  this.page = currentPage;
                  this.total = totalPages;
              }
          }
      }
      

      然后我会像这样在我的 API 调用中使用它:

      public void getStuff(int page) {
          final RestAdapter restAdapter = buildRestAdapter();
      
          // Tell the sync adapter something's been added to the queue
          ApiService apiService = restAdapter.create(ApiService.class);
          apiService.getStuff(page, new Callback<List<Stuff>>() {
              @Override
              public void success(final List<Stuff> stuffList, Response response) {
                  final APIHelper.PaginationData pagination = APIHelper.getPaginationData(response);
      
                  for (final Stuff stuff : stuffList) {
                      handleRecord(stuff);
                  }
      
                  if (pagination.page == pagination.total) {
                      App.getEventBus().postSticky(new StuffSyncEvent());
                      App.getEventBus().post(new SuccessfulSyncEvent(Stuff.class));
                  } else {
                      // Otherwise pull down the next page
                      new StuffSyncRequestAdapter().getStuff(pagination.page+1);
                  }
      
              }
      
              @Override
              public void failure(RetrofitError error) {
                  String errorMessage = error.getCause().getMessage();
                  App.getEventBus().post(new UnsuccessfulSyncEvent(Stuff.class, errorMessage));
              }
          });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-08
        • 2020-02-24
        • 2018-07-07
        • 2017-05-25
        • 2014-03-19
        • 2013-06-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多