티스토리 뷰
RecyclerView 를 구현하면서 데이터 변경사항을 알리기 위해, notifyDataSetChanged(); 를 호출한다.
근데, 이 함수는 데이터셋의 변경된 일부분에 대한 업데이트가 아닌, 데이터셋 전체를 새로운 리스트에 리로드한다. 즉, 변경할 때마다 새로운 리스트에 전체를 리로드한다는 것이며, 성능에 문제가 발생할 수 있다는 말이다.
물론, notifyDatSetChanged()가 아닌 notifyItemChanged(int), notifyItemInserted(int) ... 등의 함수를 사용하여 해결해도 된다. 그러나, 변경된 아이템의 위치정보를 알고 있어야 하고, 데이터 변경의 오퍼레이션(insert, remove, update.. )도 알고 있어야 하는 까다로움(?)이 있다.
그러니... 이참에... 까다롭게 위치정보를 알필요도 없고, 전체 데이터셋을 리로드할 필요도 없는 DiffUtil 을 적용해보자.
* 참고로 DiffUtil을 이용하면 데이터 크기에 제한이 생기는데 2^26 까지만 가능하다.
안드로이드에서 제공하는 유틸리티 클래스 중 하나인 DiffUtil을 이용하면, RecyclerView의 데이터셋에 대하여 변경된 부분을 찾고, 변경된 부분만 업데이트할 수 있다.
* 참고로 DiffUtil을 이용하는 ListAdapter를 이용하면 데이터 비교계산을 background에서 수행하게 되는데, main thread에서 많은 양의 데이터를 비교하면 순간적으로 멈춤 현상이 발생할 수 있는데 이를 background thread로 동작하도록 하여, 신경쓰지 않도록 해준다.
여기서는 그 방법에 대하여 설명한다.
- 구현 : 주요부분만 캡처했음 -
* ListAdapter<T, VH> : 서로다른 리스트의 비교 계산을 백그라운드에서 실행할 수 있도록 제공하는 어댑터
T : Adapter가 받을 수 있는 리스트의 타입
VH : Adapter가 이용하는 ViewHolder를 확장시킨 클래스
* static 형태의 DiffUtil.ItemCallback<T> : item을 비교하기 위한 Callback이며, static 인 이유는 constructor 내부에 superclass의 파라미터가 CallBack 이기 때문에 객체 생성하기 이전에 Callback이 생성되어 있어야 하기 때문이다.
T : 비교할 item의 타입
* areItemsTheSame : old item과 new item이 같은 것이냐.... true : 변동 없음, false : 변동있음
* areContentsTheSame : areItemsTheSame 이 true이면(아이템이 같음) 안에 내용도 같냐 .... true : 내용도 같음, false : 내용 변경이 있음
- DiffUtill에 대한 android developer 문서 -
https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil
- notifyDataSetChanged() 에 대한 주석 설명 -
'android' 카테고리의 다른 글
[android] 안드로이드 - 개념정리 : Context (0) | 2020.05.27 |
---|---|
[android] 안드로이드 - 개념정리 : Intent 및 PendingIntent (0) | 2020.05.27 |
[android] MVVM 패턴에서 ViewModel 객체가 생성되지 않을 때 (0) | 2020.05.17 |
[android] android studio 에서 release 버전으로 run 하는 법 (0) | 2020.04.14 |
[android] onUserLeaveHint 에 대해서 (0) | 2020.04.02 |