안드로이드 리스트뷰를 이용할때 자주 발생하는 문제를 찾아보고
해결 방법을 찾은 뒤 성능 개선 실험 결과를 공유한다.
1. convertview
2. viewHolder pattern
3. AsyncTask
4. AUIL(Android Universal Image Loader)
5. Scroll state
2. 1. 리스트뷰란?
2. 리스트뷰 사용시 자주 생기는 문제
3. 문제 분석
4. Case Study
1. Bad case
2. Convertview
3. ViewHolder
4. AsyncTask
5. AUIL
6. 스크롤 상태에 따른 최적화
5. 성능평가
6. 저장소 공유
7. Q&A
Contents
10. 2016 기술월간회의 워크샵
“리스트를 빠르게 움직이면 리스트뷰의 순서가 꼬여서 나옵니다.
시간이 지나면 정상적으로 나오고요. 그리고 스크롤 할 때 너무 버벅
거려서 보기도 않좋구요. 보통 이정도는 그냥 잘 되야 하는거 아닌가
요? 아 이것 때문에 테스트를 진행할수 가 없네요. 언제까지 수정 가
능한가요? 바로되죠? 지금 보고를 들어가야 하는데 이것때매 보고를
못하네요.”
QA 첫날의 피드백
자주생기는문제
12. 2016 기술월간회의 워크샵
비밀의 스크랩뷰(ScrapView)
ListView는 View를 재활용한다. 화면에 보여질 뷰를 inflate 한다음 스크롤시 재활용
하는 방식이다.
View inflate는 많은 비용이 드는 작업이며, 화면에 보이지도 않은 View를 미리그려
메모리의 문제가 생길 수 있기 때문에 한번 생성된 뷰를 재활용해서 데이터만 바꾸
는 구조이다.
ListView내부 코드를 보면 ScrapView라는 화면에 보여질 View 배열이 존재 한다.
ListView의 포지션에 따라 이 ScrapView의 위치가 바뀌게되는 구조로 재활용 하게
된다.
Adapter 의 getView() 의 함수에서는 convertView 라는 이름을 사용
책에는 안나오고 기
술문서에만 나옴
13. 2016 기술월간회의 워크샵
1. Inflate 가 일어날때 ViewHolder 객체에 inflate 값을 저장하고
2. 해당 row 에 ViewHolder 를 setTag() 함수를 통해 저장
3. 다시 해당 row 를 사용할때 getTag() 함수를 통해 사용
ViewHolder
14. 2016 기술월간회의 워크샵
AUIL(Android Universal Image Loader)
• 멀티 쓰레드 기반의 이미지 다운로더
• Async 방식과 Sync 방식 둘다 지원
• 쓰레드 개수, 디코더, 메모리, 디스크 캐시 등을 설정할 수 있음
• 이미지 캐싱을 메모리나 외장SD 카드에 저장 할 수 있음
• 다운로드 과정의 process 의 listener 를 지원함
15. 2016 기술월간회의 워크샵
스크롤 상태에 따른 최적화
1. 스크롤 진행중일 때에는 이미지를 로딩하지 않고
2. 스크롤이 멈추었을 때 이미지를 로딩한다.
3. 이미지 로딩전에는 기본이미지를 사용한다.
4. 단, 사용 방식에 따라 사용자의 호불호가 갈릴 수 있다.
19. 2016 기술월간회의 워크샵
ViewHolder 적용
ViewHolder 패턴을 이용해서 한번 inflate 한 객체를 캐싱함
Inflate 할때 viewHolder 객체에 저장하고
viewHolder 객체를 tag 에 저장한다.
convertView 가 존재하면
tag에서 viewHolder를 꺼내온다
viewHolder 에 포함된 뷰에 값을 업데이트 한
viewHolder 객체를 정의한다.
22. 2016 기술월간회의 워크샵
Scroll 이 멈추었을때만 Image Fetch
Scroll 이 멈추었을 때만 이미지 로드 성능 많이 향상 , but 호불호가 있음
23. 2016 기술월간회의 워크샵
1. 가상의 전화번호부를 작성
1. 브라운,코니,셀리,문,제임스 연락처가 있다고 가정을 함
2. 썸네일 이미지는 웹에 있는 이미지를 fetch 해서 사용
2. 5개의 데이터를 반복 복사해서 50,100,200개의 리스트 데이터를 구
성
예제 데이터 구성
25. 2016 기술월간회의 워크샵
성능 측정 방법 – Step2
• 각 케이스의 엑티비에 진입하면
• 최하단으로 자동 스크롤이 된다.
• 최하단까지 자동 스크롤이 되면 소요 시간과 단위 시간당 inflate 에
성공한 view 의 개수를 계산하여 성능을 측정한다.
• Row 의 개수를 50개,100개,200개를 테스트의 범위로 한다.
26. 2016 기술월간회의 워크샵
성능 테스트 결과 – 50개
method
Show count per sec
Average
1 2 3
badcase 13.13 13.11 12.45 12.90
convertview 12.12 13.62 14.21 13.32
viewholder 12.93 13.37 13.24 13.18
AsyncTask 64.15 65.53 67.75 65.81
AUIL 68.3 67.65 66.84 67.60
scrollstate 66.93 68.68 67.11 67.57
27. 2016 기술월간회의 워크샵
성능 테스트 결과 – 50개
0
10
20
30
40
50
60
70
80
badcase convertview viewholder AsyncTask AUIL scrollstate
show count per sec
Show count per sec Average
28. 2016 기술월간회의 워크샵
성능 테스트 결과 – 100개
method
Show count per sec
Average
1 2 3
badcase 0 0 0 0.00
convertview 11.16 11.28 11.16 11.20
viewholder 14.22 13.34 13.24 13.60
AsyncTask 62.65 62.65 62.9 62.73
AUIL 63.45 62.26 62.73 62.81
scrollstate 62.69 64.02 63.01 63.24
Crash 발생해서 Test 불가
29. 2016 기술월간회의 워크샵
성능 테스트 결과 – 100개
0
10
20
30
40
50
60
70
badcase convertview viewholder AsyncTask AUIL scrollstate
show count per sec
Show count per sec Average
30. 2016 기술월간회의 워크샵
성능 테스트 결과 – 200개
method
Show count per sec
Average
1 2 3
badcase 0 0 0 0
convertview 10.66 10.79 10.24 10.56333333
viewholder 15.05 10.99 11.59 12.54333333
AsyncTask 60.93 60.67 59.79 60.46333333
AUIL 60.67 61.06 60.93 60.88666667
scrollstate 60.95 60.49 61.12 60.85333333
Crash 발생해서 Test 불가
31. 2016 기술월간회의 워크샵
성능 테스트 결과 – 200개
0
10
20
30
40
50
60
70
badcase convertview viewholder AsyncTask AUIL scrollstate
show count per sec
Show count per sec Average
34. 2016 기술월간회의 워크샵
1.ConvertView 를 사용하지 않으면 매번 inflate 하면서 성능이 떨어지고 리소스를 많이 사용한다.
데이터가 아주 많을 경우에는 Crash 가 날 수도 있다.
2.리스트 최적화 시 가장 효과적인 것은 AsyncTask, AUIL 등으로 쓰레드를 사용해서 이미지를 별
도로 로딩하는 방법이다.
3.스크롤이 멈추었을 때만 쓰레드를 기동하는 방법은 호불호가 생길수 있다.
35. 2016 기술월간회의 워크샵
Further Study
1.5 개의 한정된 이미지를 rotate 해서 쓰는 경우가 의미있는 갯수의 이미지를 활용한 성능평가가
필요
2.라인스토어의 이미지가 아닌 별도의 테스트환경을 구축해야함 ( 언제 짤릴지 모름 --;;; )
3.AUIL 외의 이미지 로딩 라이브러리도 연구대상
4.단방향 스크롤이 아닌 양방향과 랜덤한 스크롤을 발생시킨 테스트가 필요함