seops

[RecyclerView] 1. RecyclerView and DiffUtil 본문

Android/Android

[RecyclerView] 1. RecyclerView and DiffUtil

seops 2020. 10. 20. 00:06

최근에 좀 바빴던 나머지, 오랜만에 블로그 글을 쓴다. (해당 내용에 대한 회고는 다음에 블로그 글로 남겨야겠다.)

 

그래도 오랜만에 약간의 신박한 주제를 갖고 왔다. 그것은 바로 RecyclerView와 DiffUtil이다.

 

RecyclerView


먼저, 구글 Docuements의 간략한 설명을 요약해보면, 다음과 같다.

RecyclerView URL : developer.android.com/guide/topics/ui/layout/recyclerview 

RecyclerView로 목록 만들기  |  Android 개발자  |  Android Developers

RecyclerView를 사용하여 동적 콘텐츠의 목록과 그리드를 표시합니다.

developer.android.com

- RecyclerView는 ListView의 more advanced and flexible 한 버전이다.

- 각 아이템들은 (RecyclerView.ViewHodler를 extends 하는) ViewHodler라는 곳에 담기고, 각 ViewHolder들은 각 아이템을 담는 View 역할을 수행한다.

- 이러한 ViewHodler들은 (RecyclerView.Adapter를 extends 하는) Adapter로 부터 관리된다.

 

- 그러면 RecyclerView가 more advanced and flexible 한 이유?

 1) 0 ~ 9 Position인 item들이 표출되는 경우, RecyclerView는 10 Position의 item을 미리 만들어 놓는다. 

 2) off-screen 된, ViewHolder를 재사용한다.

 3) 표출되는 item이 변경되면, RecyclerView.Adapter.notify...() 메서드를 통해 Adapter에게 변경사항을 알려주게 되는데, Adapter의 built-in code에서 변경사항이 있는 item들만 rebind 한다.

 

 

DiffUtil


DiffUtil Documents는 내용이 좀 어렵다.

DiffUtil URL : developer.android.com/reference/kotlin/androidx/recyclerview/widget/DiffUtil

DiffUtil  |  Android 개발자  |  Android Developers

DiffUtil open class DiffUtil DiffUtil is a utility class that calculates the difference between two lists and outputs a list of update operations that converts the first list into the second one. It can be used to calculate updates for a RecyclerView Adapt

developer.android.com

- DiffUtil은 두 개의 리스트에서 차이점을 계산해주는 utility class이다. 

- DiffUtil은 A 리스트가 B 리스트가 변환하는데 업데이트 작업 목록을 출력하는 utility class 이다.

- DiffUtil은 RecyclerView.Adapter의 업데이트 작업 목록을 계산하는 데 사용할 수 있다.

- See ListAdapter and AsyncListDiffer which can simplify the use of DiffUtil on a background thread. 

 

 

DiffUtil을 활용한 RecylcerView 성능 향상


대부분의 경우, 서버로부터 리스트를 받아오고 이를 RecyclerView에 데이터를 업데이트해주는 형식이다.

하지만 과정이 지연되게 되면, UX에 영향을 미칠 가능성이 매우 크다.

그래서 우리는 RecyclerView에 DiffUtil을 적용한다.

 

blog.kmshack.kr/RecyclerView-DiffUtil로-성능-향상하기/

RecyclerView DiffUtil로 성능 향상하기

이제 notifyDataSetChanged()는 더 이상사용을 중단하세요! 우리는 리스트를 매일 사용합니다. 사용자가 목록을 스크롤 할때 데이터를 업데이트 해야합니다. 이를 위해 서버에서 데이터를 가져와서 아

blog.kmshack.kr

위 사이트를 참고해보니, Foregroud에서 DiffUtil.Callabck을 RecyclerView에 적용하는 방법이 잘 나와있다.

근데 리스트의 개수가 많을 경우, 특히 이미지까지 포함하고 있으면... 위 DiffUtil은 무용지물일 것이다.

 

그러면 이를 Background에서 어떻게 적용해줄까?

 

jonfhancock.com/get-threading-right-with-diffutil-423378e126d2

Get Threading Right with DiffUtil

Use DiffUtil for rich animations in RecyclerView with a tiny amount of code

jonfhancock.com

이번에는 위 사이트를 참고해보자. 해당 블로거는 직접 실험까지 해본 것으로 보인다.

 

DiffUtil.Callback을 extends 하는 클래스의 override 한 메서드 안에서, 3000ms delay를 줌으로써, 정상 동작이 힘들다는 것을 보여줬다.

이에 대한 방안은 백그라운드에서 DiffUtil을 background에서 수행하는 방안을 제시했는데, 제일 마지막 Queue 방식이 가장 효율적이라고 말하고 있다.

 

 

AsyncListDiffer - DiffUtil on a background thread


위  두 번째 블로거가 제시한 Background Quere 방식의 DiffUtil Usage도 있지만, 이미 구글에서는 AsyncListDiffer라는 클래스가 있다.

자체적으로 MultiThread에 대한 처리가 되어 있기 때문에, 직접 도익화 처리를 할 필요가 없다.

 

- AsyncListDiffer는 List의 LiveData에서 값을 사용하고, 어댑터에 대한 데이터를 쉽게 표출한다.

- Diff 결과는 현재 목록이 업데이트되기 직전에, ListUpdateCalback으로 전달된다.

- submitList를 통해, 리스트 데이터를 교체한다.

 

 

ListAdapter and AsynListDiffer - Best way to use RecyclerView


- AsyncListDiffer를 더욱 간단히 사용할 수 있는 방법

- 위에서는 외부에서 아이템 리스트를 교체하는 replaceTo(), 특정 포지션의 아이템을 반환하는 getItem() 등 override를 해줘야 했지만, 이 또한 필요가 없다.

 

 

내일은 위 내용을 갖고, 직접 코딩 및 디버깅을 진행해봐야겠다.

'Android > Android' 카테고리의 다른 글

[RecyclerView] Compare RecyclerView with ListView  (1) 2020.10.31
[RecyclerView] 2. SimpleRecyclerView  (0) 2020.10.22
[Callback] 2. Singleton Class  (0) 2020.10.12
[Callback] 1. SimpleCallback  (0) 2020.10.07
[Firebase] 3. SimplePush  (0) 2020.10.04
Comments