2018 구글 I/O 에서 Paging라이브러리 발표이후 로컬(Room)로만 페이징을 했는데, Retrofit 등을 이용한 네트워크나 Cursor를 통한 페이징을 할때는 DataSource를 직접 구현해줘야한다는 사실을 알게 되었다.

그래서 DataSource의 종류에 대해서 알아보고 테스트를 해본것을 정리하고자 한다.

1.PositionalDataSoure

첫번째로 PositionalDataSource는 Position기반의 데이터 로더로 셀수 있는 고정된 사이즈를 갖는 데이터집합을 페이징 하는데 적합하다. 임의의 포지션으로부터 원하는 사이즈만큼의 데이터를 로드할 수 있다. 만약에 데이터의 사이즈를 정확하게 모르거나 런타임에만 알 수 있다면 PageKeyedDataSource나 ItemKeyedDataSource를 쓰는것을 추천한다.

placeholder 를 비활성화 시켰다면, 데이터의 사이즈를 정확히 알려줘야한다. 이를 통해서 PagedList가 사용자가 보고있는 내용을 기준으로 계속해서 데이터를 순서대로 이어갈 수 있기 때문이다. placeholder를 비활성화 시켰다면 초기화시에 onResult(List, int) 메소드를 호출하면된다.

 

 class ItemDataSource extends PositionalDataSource<Item> {
     private int computeCount() {
         // 실제 데이터의 사이즈를 반환
     }

     private List<Item> loadRangeInternal(int startPosition, int loadCount) {
         // 특정 포지션으로부터 원하는 만큼의 데이터를 이곳에서 로드
     }

     @Override
     public void loadInitial(@NonNull LoadInitialParams params,
             @NonNull LoadInitialCallback<Item> callback) {
         int totalCount = computeCount();
         int position = computeInitialLoadPosition(params, totalCount);
         int loadSize = computeInitialLoadSize(params, position, totalCount);
         callback.onResult(loadRangeInternal(position, loadSize), position, totalCount);
     }

     @Override
     public void loadRange(@NonNull LoadRangeParams params,
             @NonNull LoadRangeCallback<Item> callback) {
         callback.onResult(loadRangeInternal(params.startPosition, params.loadSize));
     }
 }

Room같은 경우는 애노테이션 프로세싱을 통해 스스로 PositionalDataSource 코드를 생성하므로 편하다.

@Dao
 interface UserDao {
     @Query("SELECT * FROM user ORDER BY mAge DESC")
     public abstract DataSource.Factory<Integer, User> loadUsersByAgeDesc();
 }

 

2. ItemKeyedDataSource

가장 일반적인 케이스이다. ItemKeyedDataSource는 서버나 데이터베이스로부터 해당 기준된 Key로부터 데이터를 로드시켜 페이징을 할 수 있게 도와준다.

처음에 RecyclerView가 화면에 나타나게 되면 ItemKeyedDataSource에서는 loadInitial() 메소드를 호출하게 된다. 초기화에 필요한 Key와 로드하고싶은 데이터의 사이즈 등을 인자로 받아 서버나 데이터베이스 등으로부터 데이터를 로드 할 수 있다.

 

이후 RecyclerView를 스크롤 하게 되면 loadAfter()를 호출하게 되고, 이때 기준 Key를 통해 다음 페이지를 로드 하면된다. 여기서 생각해 볼 수 있는게 Key를 통해 다음 페이지를 가져오려는데 데이터베이스의 내용이 변경된다면 어떻게 될까? 걱정할 필요없다. Key의 비교를 통해 중복된 데이터는 자연스럽게 걸러지게 되고, 애니메이션과 함께 UI가 갱신되게 된다.

 

3.PageKeyedDataSource

ItemKeyedDataSource가 하나의 아이템키에 대한 기준으로 데이터를 가져왔다면, PageKeyedDataSource는 페이지키 단위로 데이터를 불러들인다. 단 데이터베이스로부터 다음페이지와 이전페이지를 받아야한다.

 

먼저 loadInitial() 메소드를 통해 한페이지의 데이터를 받아야한다. 

이후 사용자의 RecyclerView 스크롤을 통해 loadAfter를 호출하게 되고 다음 페이지를 로드 하면된다.

페이징 라이브러리를 직접 사용해보니 대용량의 데이터를 빠르고, 간편하게 처리 할 수 있게 되었다. 더 이상 방대한 데이터를 한번에 불러와 메모리에 적재하는것을 기다리지 않아도 된다. 그때 그때 필요한만큼만 로드하여 사용자와 앱간의 반응성을 높일 수 있다. 나온지 얼마 되지 않은 라이브러리라 앞으로가 더욱 기대가 된다.

카테고리: 미분류

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.