your programing

페이징 라이브러리-페이지 및 크기를 가져 오는 API가있는 네트워크 + db에 대한 경계 콜백

lovepro 2020. 12. 31. 23:08
반응형

페이징 라이브러리-페이지 및 크기를 가져 오는 API가있는 네트워크 + db에 대한 경계 콜백


짧은 질문 :

페이지 + 크기를 사용하여 새 페이지와 BoundaryCallback클래스 를로드하는 API를 사용하여 아키텍처 구성 요소의 Paging 라이브러리에서 데이터베이스 + 네트워크를 처리하는 올바른 방법은 무엇입니까 ?

연구 및 설명

현재 BoundaryCallback아키텍처 구성 요소에 대한 페이징 라이브러리에서 사용되는 클래스 는이 요소가 어디에 있는지에 대한 실제 컨텍스트없이 목록에있는 요소의 인스턴스를 매개 변수로받습니다. onItemAtFrontLoaded에서 발생합니다 onItemAtEndLoaded.

내 API는 다음 데이터 청크를로드하기 위해 페이지와 페이지 크기를 수신해야합니다. 페이지 목록 작성기의 일부로 추가 된 경계 콜백은 프리 페치 거리 및 페이지 크기에 따라 데이터의 다음 페이지를로드 할시기를 알려줍니다.

API가 페이지 번호와 제공하는 페이지의 크기를 필요로하기 때문에, 난 그냥 제공으로 목록에서 요소 중 하나 받아 API에 저를 보낼 수있는 방법을 볼 수 없습니다 onItemAtFrontLoadedonItemAtEndLoaded. 이 링크 의 Google 예제를 확인하면 마지막 요소의 이름을 사용하여 다음 요소를 가져 오지만 페이지 + 크기가있는 Api에는 맞지 않습니다.

또한를 사용하는 네트워크 만있는 또 다른 예가 PagedKeyedDatasource있지만 데이터베이스 및 BoundaryCallback과 혼합하는 방법에 대한 샘플이나 단서가 없습니다.

편집 : 지금까지 찾은 유일한 해결책은 공유 환경 설정에 마지막으로로드 된 페이지를 저장하는 것이지만 그것은 더러운 속임수처럼 들립니다.

공식적인 의견은 https://github.com/googlesamples/android-architecture-components/issues/252#issuecomment-392119468참조 하세요 .


나는 이것을 구현합니다.

PagedList.BoundaryCallback<Produto> boundaryCallbackNovidades = new PagedList.BoundaryCallback<Produto>(){
    int proxPagina;
    boolean jaAtualizouInicio=false;

    public void onZeroItemsLoaded() {
        requestProdutos(
            webService.pesquisarNovidadesDepoisDe(LocalDateTime.now().format(Util.formatterDataTime), 0, 20));
    }

    public void onItemAtFrontLoaded(@NonNull Produto itemAtFront) {
        if(!jaAtualizouInicio)
            requestProdutos(
                webService.pesquisarNovidadesMaisRecentesQue(itemAtFront.data.format(Util.formatterDataTime)));
        jaAtualizouInicio=true;
    }

    public void onItemAtEndLoaded(@NonNull Produto itemAtEnd) {
        requestProdutos(
            webService.pesquisarNovidadesDepoisDe(LocalDateTime.now().format(Util.formatterDataTime), proxPagina++, 20));
    }
};


public LiveData<PagedList<Produto>> getNovidades(){
    if(novidades==null){
        novidades = new LivePagedListBuilder<>(produtoDao.produtosNovidades(),
                10)
                .setBoundaryCallback(boundaryCallbackNovidades)
                .build();
    }
    return novidades;
}

항상 N=10서버에서 페이지 당 항목을 가져 와서 db에 저장 한다고 가정 해 보겠습니다 . sql 쿼리를 사용하여 db의 항목 수를 얻고 SELECT COUNT(*) FROM tbl변수에 저장할 수 있습니다 count. 이제 다음에 요청해야하는 페이지 번호를 얻으려면 다음을 사용하십시오.

val nextPage: Int = (count / N) + 1

문서는 이 문제에 대답이있다 :

항목 키 네트워크 API를 사용하지 않는 경우 페이지 키 또는 페이지 인덱싱을 사용할 수 있습니다. 이 경우 페이징 라이브러리는 BoundaryCallback에 사용 된 페이지 키 또는 인덱스에 대해 알지 못하므로 직접 추적해야합니다. 다음 두 가지 방법 중 하나로이 작업을 수행 할 수 있습니다.

로컬 저장소 페이지 키

If you want to perfectly resume your query, even if the app is killed and resumed, you can store the key on disk. Note that with a positional/page index network API, there's a simple way to do this, by using the listSize as an input to the next load (or listSize / NETWORK_PAGE_SIZE, for page indexing). The current list size isn't passed to the BoundaryCallback though. This is because the PagedList doesn't necessarily know the number of items in local storage. Placeholders may be disabled, or the DataSource may not count total number of items.

Instead, for these positional cases, you can query the database for the number of items, and pass that to the network.

In-Memory Page key

Often it doesn't make sense to query the next page from network if the last page you fetched was loaded many hours or days before. If you keep the key in memory, you can refresh any time you start paging from a network source. Store the next key in memory, inside your BoundaryCallback. When you create a new BoundaryCallback when creating a new LiveData/Observable of PagedList, refresh data. For example, in the Paging Codelab, the GitHub network page index is stored in memory.

And links to an example Codelab: https://codelabs.developers.google.com/codelabs/android-paging/index.html#8

ReferenceURL : https://stackoverflow.com/questions/50456919/paging-library-boundary-callback-for-network-db-with-api-taking-page-and-siz

반응형