Paging library - Boundary callback for network + db with API taking page and size

后端 未结 4 1028
小蘑菇
小蘑菇 2021-02-03 16:35

Short question:

What is the correct way to handle database + network on the Paging library from Architecture components, using an API that uses page + s

相关标签:
4条回答
  • 2021-02-03 17:14

    I implement this:

    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;
    }
    
    0 讨论(0)
  • 2021-02-03 17:22

    Lets say you always fetch N=10 items per page from the server & then store it in db. You can get the number of items in db using the sql query SELECT COUNT(*) FROM tbl & store it in variable count. Now to get the page number that should be requested next, use:

    val nextPage: Int = (count / N) + 1
    
    0 讨论(0)
  • 2021-02-03 17:25

    The documentation has this to say on the issue:

    If you aren't using an item-keyed network API, you may be using page-keyed, or page-indexed. If this is the case, the paging library doesn't know about the page key or index used in the BoundaryCallback, so you need to track it yourself. You can do this in one of two ways:

    Local storage Page key

    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

    0 讨论(0)
  • 2021-02-03 17:33

    I have a similar API (pageNum + size), I have 2 extra fields in my data class, pageNum and pageSize with defaults 1 and PAGE_SIZE respectively.

    If you're using Network+DB then you'll have onZeroItemsLoaded and onItemAtEndLoaded, In onZeroItemsLoaded send pageNum and pageSize as it is, and in onItemAtEndLoaded increment pageSize by 1 and then send.

    Let's say you have a method fetchData(pageNum, pageSize) when you receive result in this just update the pageNum and pageSize accordingly in each item of this page.

    0 讨论(0)
提交回复
热议问题