윈도우 백그라운드 & UI 속도
안드로이드의 어떤 애플리케이션은 UI 의 속도를 최대한 끌어올릴 필요가 있습니다. 방법은 여러가지가 있습니다.
이번 문서에서는 애플리케이션의 그리기 성능과 액티비티의 지각(느낄 수 있는) 할 수 있는 스타트업 속도를 어떻게 향상시킬수 있는지 알아봅니다.
이 두가지 성능향상을 위한 기법은 한 요소에 의해 결정됩니다. 윈도우의 백그라운드 Drawable 입니다.
윈도우 백그라운드라는 용어는 약간은 오해의 소지가 있습니다. 하지만 액티비티에서 setContentView() 메서드를 이용해서 UI를 구축한다면
안드로이드는 액티비티의 윈도우에 뷰를 추가합니다. 하지만 윈도우는 단지 뷰만 추가하는 것이 아니라 몇몇 다른 요소들을 포함합니다.
가장 중요한 요소는 T-Mobile G1에서 사용되고 있는 DecorView 입니다.
아래 표에서 뷰 계층(View Hierarchy) 에서 확인해보죠.
DecorView는 윈도우의 Drawable을 실제로 담고 있는 뷰입니다.
액티비티에서 getWindow().setBackgroundDrawable() 메서드를 호출하고 DecorView의 백그라운드 Drawable을 바꾸면 윈도우의 백그라운드가 바뀝니다.
이 설정은 매우 구체적인 설정이고 차후버전이나 심지어 다른 기기들에서도 바꿀 수 있습니다.
개발시에 표준 안드로이드 테마를 사용한다면 안드로이드는 기본 백그라운드 Drawable을 액티비티의 기본 배경으로 사용합니다.
T-Mobile G1 에서 현재 사용하고 있는 표준 테마는 ColorDrawable 입니다. 대부분의 애플리케이션에서 백그라운드 Drawable은 잘 동작하며 혼자서도 동작이 가능합니다.
하지만 이 백그라운드 Drawable은 애플리케이션의 그리기 성능에 영향을 미칠 수 있습니다.
애플리케이션이 백그라운드에 항상 투명 사진을 그리는 예제를 한 번 보죠.
위의 스크린샷에서 윈도우의 백그라운드가 보이지 않는 것을 확인 할 수 있습니다.
윈도우의 백그라운드 전체가 ImageView 에 가려져 있죠. 애플리케이션이 44FPS(초당 프레임수)의 속도로 이미지를 그리고 있습니다.
이 애플리케이션이 더 빠르게 이미지를 그리게 하는 방법은 백그라운드 Drawable 을 제거하는 것입니다.
UI가 완전히 투명이기 때문에 백그라운드에 이미지를 그리는 것은 너무나 소모적이죠.
백그라운드 이미지를 제거하는 것은 성능을 끌어 올리는데 아주 좋습니다.
위의 스크린샷에서 백그라운드 이미지를 제거한 후에 FPS를 재어보니 51FPS가 나왔습니다. 초당 3밀리초의 차이는 T-Mobile G1의 메모리 버스에서 생기는 지연효과로
풀스크린 이미지의 픽셀을 메모리 버스로 옮기는데 걸리는 시간을 의미합니다. 기본 백그라운드가 훨씬 더 화려하고 메모리 상주크기가 높다면 이 차이는 더 확연해 집니다.
윈도우의 백그라운드를 쉽게 삭제하는 방법은 커스텀 테마를 사용하는 것입니다. res/values/theme.xml 파일을 만듭니다.
그리고 아래의 코드를 넣습니다.
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>
이제 android:theme="@style/Theme.NoBackground" 속성을 <activity /> 나 <application />태그에 삽입하여 개발하고자하는 액티비티에 적용시킵니다.
MapView 나 WebView를 사용하거나 풀스크린 투명 뷰를 사용하는 애플리케이션을 개발한다면 매우 손쉽게 적용시킬 수 있습니다.
투명 뷰와 안드로이드 : 이 작업은 최적화 작업이 필요한데 안드로이드 UI 툴은 투명 자식객체로 숨겨진 뷰들을 다시 그리는 것을 방지할 만큼 똑똑하진 않기 때문입니다.
이 최적화 작업이 실행되지 않은 가장 주요한 이유는 안드로이드 애플리케이션에는 보통 투명 뷰가 없거나 아주 소수이기 때문입니다.
상황이 이렇다해도 최대한 이른 시기안에 이 최적화 작업을 진행하겠습니다. 좀 더 일찍 실행하지 못한 점이 죄송합니다.(번역자 주: 프레젠테이션에서 발표한 자료같음)
테마를 사용해서 윈도우의 백그라운드를 바꾸는 것 또한 액티비티의 스타트업 속도를 향상시킬 수 있습니다.
단, 텍스쳐나 로고를 이용한 커스텀 백그라운드를 사용하는 액티비티에만 적용됩니다.
아래 스크린샷에서 보이는 책장선반 애플리케이션이 좋은 보기입니다.
만약 이 애플리케이션의 XML이나 onCreate()메서드에서 그냥 나무 백그라운드를 지정해버린다면 사용자는 기본테마와 어두운 백그라운드를 보게 됩니다.
나무 텍스쳐(질감)은 context 뷰의 로드 후와 첫번째 레이아웃/그리기 작업이 끝난다음에만 나타나게 됩니다.
이런 작업을 보는 사용자는 애플리케이션이 불안하고 로딩하는데 시간이 오래 걸린다고 생각합니다.(실제로도 그렇습니다)
대신에 애플리케이션이 나무 백그라운드를 테마로 정의하고 애플리케이션이 시작되자마자 안드로이드 시스템이 이 설정을 적용시킨다면 사용자는 기본 테마를 보지 않게 되고
애플리케이션이 빠릿빠릿하고 바로 실행되어 빠르다는 인상을 갖게 됩니다.
메모리와 디스크 사용량을 줄이기 위해서는 res/drawable/background_shelf.xml 파일에 아래와 같이 백그라운드 타일을 정의합니다.
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/shelf_panel"
android:tileMode="repeat" />
이 Drawable 은 테마를 참조합니다.
<resources>
<style name="Theme.Shelves" parent="android:Theme">
<item name="android:windowBackground">@drawable/background_shelf</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
Google Maps 애플리케이션에 위에서 보인 기법과 똑같은 기법이 사용되었습니다. 애플리케이션이 구동되면 사용자는 즉시 MapView의 타일들을 보게 됩니다.
테마는 MapView에서 타일을 로드하는 것과 똑같이 보이는 타일 백그라운드를 사용합니다.
가끔식 보면 최고의 기법들은 아주 간단합니다.
다음번에 투명 UI 혹은 커스텀 백그라운드를 사용하는 액티비티를 만들때는 윈도우의 백그라운드를 바꾸는 걸 기억하세요.