1

I am using Android Pagination Library... It's working in a weird way - Items keep loading infinitely, there is no stop even when there are no more data to load.

For example, I have 2 Items to load, instead of loading just the 2 items and stop loading, It keeps loading the 2 items repeatedly... Here is a gif of what I am facing.

Image loading

First here is my repository

CommentDataSource.java

Note - when I change the value of "PAGE_SIZE" to "1", It seems to work but the whole purpose of the pagination defeated as ALL the items are loaded at once. (I tested with more items)

public class CommentDataSource extends PageKeyedDataSource<Long, Comment> {
public static int PAGE_SIZE = 10;
public static long FIRST_PAGE = 1;

 public CommentDataSource(){
  }

 @Override
 public void loadInitial(@NonNull final LoadInitialParams<Long> params, @NonNull final 
 LoadInitialCallback<Long, Comment> callback) {
 RestApi restApi = RetrofitApi.create();

 Call<CommentResponse> call = restApi.getComments(FIRST_PAGE);

 call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                callback.onResult(responseItems, null, FIRST_PAGE + 1);
            }
        }

   @Override
public void loadBefore(@NonNull final LoadParams<Long> params, @NonNull final LoadCallback<Long, Comment> callback) {
    RestApi restApi = RetrofitApi.create();

    Call<CommentResponse> call = restApi.getComments(params.key);

    call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                long key;
                if(params.key > 1){
                    key = params.key - 1;
                }
                else {
                    key = 0;
                }
                callback.onResult(responseItems, key);
            }
        }
    });

}

@Override
public void loadAfter(@NonNull final LoadParams<Long> params, @NonNull final LoadCallback<Long, Comment> callback) {

    RestApi restApi = RetrofitApi.create();

    Call<CommentResponse> call = restApi.getComments(params.key);

    call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                callback.onResult(responseItems, params.key + 1);
            }
        }

    });
 }
}

Here is my ViewModel

CommentViewModel.java

public class CommentViewModel extends ViewModel {
public CommentViewModel(){
    CommentDataFactory commentDataFactory = new CommentDataFactory();
    liveDataSource = commentDataFactory.commentLiveDataSource;

    progressBar = Transformations.switchMap(liveDataSource, CommentDataSource::getProgressBar);

    PagedList.Config config = new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setPageSize(CommentDataSource.PAGE_SIZE)
            .build();

    commentPagedList = new LivePagedListBuilder<>(commentDataFactory, config).build();
}


public LiveData<PagedList<Comment>> getCommentData(){
    return commentPagedList;
}

public void getRefreshedData(){
    getCommentData().getValue().getDataSource().invalidate();
   } 
 }

Here is my PHP code for database query which returns in JSON format.

get_comments.php

<?php
  $limit = 10;

  //find out how many rows are in the table
  $sql = "SELECT count(*) FROM comments"; 
  $result = $conn->prepare($sql); 
  $result->execute();
  $total = $result->fetchColumn();
  $totalpages = ceil($total/$limit);

  if (isset($_GET['page']) && is_numeric($_GET['page'])) {
  $currentpage =  $_GET['page'];
  } else {
  // default page num
  $currentpage = 1;
  }

if ($currentpage > $totalpages) {
 // set current page to last page
 $currentpage = $totalpages;
 }

 // if current page is less than first page... 
if ($currentpage < 1) {
  $currentpage = 1; 
 } 

 //the offset of the list, based on current page 
 $offset = ($currentpage - 1) * $limit;


  $stmt = "SELECT * FROM comments ORDER by id DESC LIMIT $offset, $limit";
  $result = $conn->prepare($stmt); 
  $result->execute();

  $response = array(); 

  while ($row = $result->fetch()) {

  $temp['id']=$row['id'];
  $temp['image_id']=$row['image_id'];
  $temp['comment']=$row['comment'];
  $temp['comment_by']=$row['comment_by'];
  $temp['date_posted']=$row['date_posted'];

  array_push($response, $temp);

  $obj = (object) [ 
 'data' =>  $response
  ];

 }
echo json_encode($obj); 
?>

These are the codes I feel are needed...I didn't add the adapter and the factory but if need be, I can add other codes...Someone pls help as I have been on this for days...

"

Krishna Sony
  • 1,286
  • 13
  • 27
Ibramazin
  • 958
  • 10
  • 30
  • your DataSource is already async so you can make retrofit calls sync by using call.execute(). – Nikola Srdoč Jun 11 '20 at 11:48
  • How many pages are there in your $totalpages variable in php – Vivek Singh Jun 11 '20 at 12:34
  • @NikolaSrdoč I dont understand?? – Ibramazin Jun 11 '20 at 14:30
  • @VivekSingh totalpages returned 1 in php. Normally, the total pages is total/limit...In my case it is 2/10 = 0.2....But since current page is greater than 0.2...$totalpages is set to 1 from the PHP code.... – Ibramazin Jun 11 '20 at 14:34
  • @Ibramazin The loading methods in the CommentDataSource are running in a background thread. This means you should do synchronous work on that thread – Nikola Srdoč Jun 11 '20 at 14:40
  • @NikolaSrdoč I thought synchronous requests trigger app crashes..?? – Ibramazin Jun 11 '20 at 14:46
  • you can find reference here: [link](https://developer.android.com/topic/libraries/architecture/paging) Network only: To display data from a backend server, use the synchronous version of the Retrofit API to load information into your own custom DataSource object. – Nikola Srdoč Jun 11 '20 at 14:46
  • Thanks you..@NikolaSrdoč I have switched to synchronous call. I got it to work thanks to Vivek Singh....But I am curious to know if there are implications to using the synchronous retrofit call....Cause most tutorials I see use the Async call..?? – Ibramazin Jun 11 '20 at 18:29
  • Probably guys from google have updated their documentation saying how to use retrofit in DataSource after those tutorials were written...No implications when you doing sync retrofit call on a background thread...If you do it on ui thread the app will not compile with NetworkOnMainThreadException – Nikola Srdoč Jun 12 '20 at 03:21

1 Answers1

1

I think i got why it is loading again and again, here is why:

Firts in the loadInitial() of your CommentDataSource you are passing FIRST_PAGE + 1 in the line callback.onResult(responseItems, null, FIRST_PAGE + 1); of the onReponse(), that means in the loadAfter() that FIRST_PAGE + 1 get passed as page number 2 in the line restApi.getComments(params.key) but page number 2 dosn't exist in your database and you are setting the same page number if the page number is greater than 1 in your php

if ($currentpage > $totalpages) {
 // set current page to last page
 $currentpage = $totalpages;
 }

So you are calling page number 1 again and again. In the loadAfter() you are calling the page 1 again and then again and again.

Vivek Singh
  • 1,142
  • 14
  • 32
  • It works now....I had to remove those lines of code if ($currentpage > $totalpages) { // set current page to last page $currentpage = $totalpages; } THANKSS.... – Ibramazin Jun 11 '20 at 18:26