본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Android/안드로이드] 왜 ListView 가 검은 배경을 가지는가? Android 최적화.

by 돼지왕 왕돼지 2012. 4. 16.
반응형

안녕하세요 돼지왕 왕돼지입니다.

오늘은 "왜 ListView 가 검은 배경을 가지는가? Android 최적화" 라는 주제로 이야기를 하고자 합니다.

이 글은  http://android-developers.blogspot.com/2009/01/why-is-my-list-black-android.html 내용을 의역한 내용입니다.

 

왜 ListView 가 검은 배경을 가지는가? Android 최적화.

ListView 는 Android에서 가장 자주 쓰이는 widget 중 하나입니다. 사용하기도 쉽고, 유동적이며, 강력하죠. 하지만 한편으로는 이해하기 어려운 녀석 중 하나입니다.


가장 흔하게 접하는 이슈는 custom background 를 set 했을 때입니다. 기본적으로 다른 android widget 과 마찬가지로 ListView 는 default window background 를 볼 수 있도록, 투명한 배경을 가지고 있습니다. default background 는 dark theme에서 #FF191919 색을 가지고 있죠. 추가적으로 ListView 는 fading edge 가 기본적으로 enable 되어 있는데 이 녀석은 리스트의 상단과 하단에 살짝 흐려지는 효과를 넣는 녀석이죠. 이 효과는 ListView 가 scroll 될 수 있다는 UX 를 주기 위해서 존재합니다.

 
이 fade effect 는 Canvas.saveLayerAlpha() 와 Porter-Duff Destination Out blending mode 를 이용하여 구현되어 있습니다. 애석하게도, custom background 를 사용하거나, window background color 를 바꾸면 이상하게 보이는 현상이 발생합니다. 아래 두 screenshot 이 window background 를 바꿨을 떄 일어나는 상황에 대해 보여줍니다. 왼쪽은 List 에 operation 을 가하지 않은 초기 모습이고, 오른쪽은 scroll 이 시작되었을 떄의 화면입니다.

 

 


이 그리는 문제는 ListView 류 ( GridView 는 제외 )가 기본적으로 android framework 의 최적화를 사용하기 때문입니다. 앞서 fade effect 가 Porter-Duff blending mode 를 사용한다고 했죠? 이 구현은 잘 작동은 하지만, 매우 비중이 큰 작업이어서 drawing performance 를 조금 떨어뜨릴 수 있습니다. 왜냐하면 스크린의 일부를 capture 한 후에 blending 을 해야 하기 때문입니다. ( 이것은 memory 를 다시 읽어오는 작업을 거칩니다. )



ListView 는 대부분 고전된 배경화면과 함께 작동하기 때문에, 저런 비싼 작업을 계속 수행할 이유가 없습니다. 그래서 android 는 cache color hint 라고 불리는 최적화를 사용한 것이지요. cache color hint 는 window의 background color ( #191919 in dark theme ) 의 RGB color 가 set 됩니다. 이 hint 값이 설정되면 ListView 는 ( view 역시 ) 고정 배경색과 함께 그려진다는 것을 알게 되고, 이것이 saveLayerAlpha() 와 Porter-DUff 의 값비싼 작업을 수행할 필요 없이 간단한 gradient 로 변환시켜줍니다. 이 gradient 는 완전 투명부터 cache color 까지의 value 를 잘 표현하여 만듭니다. 이는 왼쪽 하단의 이미지를 통해 볼 수 있습니다. 하지만 이것이 list 가 scroll 될 때 검은색으로 변하는 이유를 설명하지는 못합니다.

이전에 설명했듯 ListView 는 투명한 background 를 기본으로 가집니다. 다른 android widget 도 마찬가지구요. 이 말인즉슥, ListView 가 children 을 redraw 할 때 children 은 window의 배경과 blend 된다는 의미입니다. 다시 말해, 이것은 memory 를 다시 읽는 비용을 부과하기 때문에 스크롤을 할 때나 플리킹을 할 때는 엄청난 퍼포먼스 저하를 가져올 수 있습니다. 1초에 수십회나 blend 작업이 이루어지기 때문이죠. scroll 중 drawing performance 를 올리기 위해서는 android framework 는 cache color hint 값을 재사용합니다. 이 hint 값이 설정되어 있다면, framework 는 Bitmap 을 hint value로 채운 후에 list 의 child 를 그 위에 복사하는 방식을 사용합니다. ( scrolling cache 가 켜져 있어야 합니다. ) ListView 는 이 bitmap 을 screen 에 바로 그려줍니다. 이 bitmap 은 불투명하기 때문에 blending 이 필요가 없지요. default cache color hint 가 #191919 이기 때문에, scroll 할 때 검은 배경이 나온 것입니다.

이 이슈를 수정하기 위해서 당신이 해야 할 것은 cache color hint 최적화를 disable 하거나( non-solid color background 경우 ), 이 hint 를 적절한 sold color 값으로 변경해주어야 합니다. 이 작업은 code 를 통해서 할 수도 있고, XML 을 통해서 할 수도 있습니다. ( xml은 android:cacheColorHint 옵션을 사용합니다. ) 최적화를 disable 하려면 투명 색상인 #00000000 을 set 해주면 됩니다. 아래 screen shot 은 android:cacheColorHint = "#00000000" 을 xml layout file 에 기술해준 예입니다.


보다시피 fade 는 나무 배경에 대해 정확하게 작동합니다. 나는 cache color hint 기능이 매우 흥미롭다고 생각합니다. 왜냐하면 개발자가 어려워 할 수 있는 몇몇 상황들에 대해 어떻게 최적화를 할 수 있는지를 보여주니까 말이죠. 하지만, 이 경우는 개발자에게 복잡도를 훨씬 많이 증가시킬 수도 있죠.


도움이 되셨다면 손가락 꾸욱~




  





반응형

댓글