Paiging라이브러리 개요

페이징 라이브러리는 데이터 로딩을 쉽게, 점진적으로 그리고 아주 우아하게 RecyclerView와 함께 작동하도록 도와주는 라이브러리이다.
많은 앱들이 많은 양의 데이타를 로딩해두고, 실제로는 전체의 일부만을 실제로 보여주게 된다.
페이징라이브러리는 합리적으로 이런 데이터의 부분집합만을 표현하고 관찰하는것을 도와준다. 이런 기능은 몇몇 장점을 갖게 된다.

  • 데이터를 점진적으로 로딩하기 때문에 네트워크 사용량 및 시스템 리소스를 적게 쓸 수 있다. 무제한 요금제가 아닌 제한적으로 작은 용량의 data 요금제를 쓰는 사용자에게는 도움이 많이 된다.
  • 새로운 데이터를 받아오거나 갱신하는중에도 애플리케이션은 지속적으로 사용자의 입력에 빠르게 반응 할 수 있다.

페이징 라이브러리 설정하기

애플리케이션 모듈레벨에 있는 build.gradle에 추가해주세요.

dependencies {
    def paging_version = "1.0.0"
    implementation "android.arch.paging:runtime:$paging_version"
}

 

라이브러리의 구조

페이징 라이브러리의 핵심 컴포넌트는 PagedList 클래스 입니다. 이 클래스는 애플리케이션에서 필요로 하는 데이터 또는 페이지들을 특정 덩어리 단위로 비동기적으로 로딩하여 담아두는 collection클래스입니다.  이 클래스는 앱내의 다른 구성요소들 사이에서 중재하는 역할을 합니다.

Data

PagedList의 각 인스턴스는 최신의 데이터를 DataSource로 부터 불러오게 됩니다. 서버나 로컬 데이터베이스부터 가져온 Data가 PageList객체로 들어가게 됩니다.
페이징 라이브러리는 독립적인 데이터베이터 그리고 서버와 통신하는 데이터 베이스를 포함하여, 다양한 아키텍처를 지원합니다.

UI

PagedList클래스는 PagedListAdapter와 같이 동작하여 RecyclerView에 아이템들을 표현하게 됩니다. 이러한 클래스들은 함께 동작하여 이미 로딩된 데이터가 있으면 그대로 보여주고, 그렇지 않으면 데이터를 불러와서 자연스럽게 화면에 표시해줍니다.
페이징 라이브러리는 다른 Android Architecture Component와 같이 사용하는것을 강력하게 권장합니다.  페이지 라이브러리는 특히 LiveData나 RxJava 객체같은 Observable 객체를 다룹니다. PagedList에서는 이러한 객체를 생성하여 UI로 표현하게 되고 그러는 동안에도 UI컨트롤러의 생명주기를 중시하여 생명주기로 부터 생기는 에러등을 미연에 방지할 수 있습니다.
 

Room Database를 사용하는 예제

Room에 대해서 더 알아보고 싶다면 아래 링크를 참조해주세요.
Room 에 대해서 알아보기

@Dao
interface ConcertDao {
    @Query("SELECT * FROM user ORDER BY concert DESC")
    fun concertsByDate(): DataSource.Factory<Int, Concert>
}

DataSource.Factory<Int, *>에서 Int자료형 인자는 룸에게 어떤 포지션의 데이터를 사용할 지에 대해 알려주게 됩니다.

class MyViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> = LivePagedListBuilder(
            concertDao.concertsByDate(),
            /* page size */ 20
    ).build()
}

View에게 데이터를 전달 할 ViewModel에서는 데이터를 가져오는 작업을 하게 됩니다. Paging을 쓰기 위해서는 데이터 콜렉션 타입이 반드시 PageList여야 합니다. PageList는 LivePageListBuilder를 통해 만들 수 있습니다. 위의 예제에서는 DataSource와 페이지 사이즈를 인자로 받아 생성하고 있으며, 더많은 설정을 위해서는 PagedList.Config를 만들어서 빌더를 생성하면 됩니다.
 

class MyActivity : AppCompatActivity() {
    public override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)
        val viewModel = ViewModelProviders.of(this)
                .get(MyViewModel::class.java!!)
        val recyclerView = findViewById(R.id.concert_list)
        val adapter = ConcertAdapter()
        viewModel.concertList.observe(this, { pagedList ->
                adapter.submitList(pagedList) })
        recyclerView.setAdapter(adapter)
    }
}

이제 액티비티를 살펴보도록 하겠습니다. 액티비티에서는 일반적으로 뷰모델, 리사이클러뷰, 어댑터 등을 설정해주면됩니다.

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert = getItem(position)
        if (concert != null) {
            holder.bindTo(concert)
        } else {
            // Null일경우 PagedListAdapter는 자동으로 데이터베이스로부터 아이템을 로드하여
            // 해당 행을 갱신 하게 됩니다.
            holder.clear()
        }
    }
    companion object {
        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
            override fun areItemsTheSame(oldConcert: Concert,
                    newConcert: Concert): Boolean =
                    oldConcert.id == newConcert.id
            override fun areContentsTheSame(oldConcert: Concert,
                    newConcert: Concert): Boolean =
                    oldConcert == newConcert
        }
    }
}

리싸이클러뷰에서 가장 중요한 어댑터 부분입니다.
리싸이클러뷰의 성능을 개선하기 위해 DiffUtil.ItemCallback을 쓰실텐데요.
페이징 라이브러리에서는 DiffUtil.ItemCallback 반드시 구현해야합니다.

카테고리: 미분류

0개의 댓글

답글 남기기

Avatar placeholder

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