2014-07-22 13 views
9

Buduję aplikację za pomocą modernizacji. Wszystko działa płynnie, ale martwię się wielkością żądań interfejsu API i chcę je podzielić za pomocą stronicowania.Obsługa paginacji w modernizacji

Jaka jest najlepsza strategia automatycznego przechodzenia przez interfejs API za pomocą funkcji Retrofit, aby wszystkie dostępne dane były domyślnie pobierane?

Odpowiedz

2

Więc skończyło się na rozwiązywaniu mój problem tak:

używam winogron na moim serwerze, więc zainstalowałem gem Grape-kaminari do obsługi stronicowania po stronie serwera. Grape-kaminari zapewnia zapytanie strony o adresy URL i dodaje przydatne informacje stronicowania do odpowiedzi nagłówka.

napisałem małą klasę pozwala mi automatycznie recurse za pośrednictwem stron, dopóki nie spożywane wszystkie dane z 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; 
     } 
    } 
} 

bym następnie wykorzystać go w moje wezwanie API tak:

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)); 
     } 
    }); 
} 
7

Po pierwsze, paginacja musi być obsługiwana przez usługę backendu, z której korzystasz. Po drugie, jeśli szukasz przykładu, jak można to zaimplementować od strony klienta za pomocą modernizacji, polecam przyjrzeć się projektowi u2020 z @JakeWharton. Interfejs modernizacji GalleryService wdraża taki mechanizm w bardzo prosty sposób. Oto link do samego interfejsu.

Oto światło przykład na podstawie projektu u2020

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

Śledząc całkowitą ilość przedmiotów już pobrane z serwisu spoczynku i predefiniowany maksymalnie elementów na stronie można obliczyć indeks strony niezbędne, aby zadzwonić twoja usługa odpoczynku do następnego zestawu elementów do pobrania.

Możesz wtedy nazywać Cię api w ten sposób.

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

Jest to bardzo lekki przykład oparty na projekcie u2020, ale mam nadzieję, że daje on wyobrażenie o tym, jak go zaatakować.

Powiązane problemy