안드로이드 앱 성능 최적화 – 2. 최적의 레이아웃 구성 확인방법



안드로이드 플랫폼이 국내에 출시 된지도 약 3년이라는 시간이 지났습니다. 개발자들도 많은 경험이 축척되면서 앱의 퀄리티는 점점더 높아지고 있으나, 아직 해외 만큼의 퀄리티를 가진 국내앱은 손에 꼽힐 정도라고 생각합니다. 이런 퀄리티 높은 앱을 개발하기위해 좀 더 성능을 높이는 방법에 대해 소개 하기위해 “안드로이드 앱 성능 최적화”라는 주제를 가지고 연제글을 쓰게 되었습니다.

안드로이드 앱 성능 최적화 – 2. 최적의 레이아웃 구성확인 방법

레이아웃이 그려지기 위해서는 Main Thread에서 xml의 레이아웃을 파싱해서 해당 View를 그립니다. 레이아웃의 구조가 많거나 복잡하면 그리는 시간이 오래 걸리기때문에 사용자들은 반응이 느리다라고 느끼게 됩니다. 앱이 좀더 빠르게 작동되도록 하기위해서 레이아웃 구조 최적화는 필수 요소입니다.

최적화된 레이아웃인지 확인 하는 방법중 안드로이드 4.2부터 개발자 옵션에 불필요하게 드로잉 되는 영역을 알려주는 기능이 있습니다. Show GPU overdraw를 활성화 한다음 앱을 실행하면 드로잉 횟수를 색상으로 표현 해줍니다.

Blue 1번 

Green 2번 

Light Red 3번

Dark Red 4번 이상

구글에서는 Light Red인 3번 정도까지는 무리 없으며 Dark Red는 최대한 없게 만들어라고 제안해주고 있습니다. 

여기에서 Draw되는 영역은 테마의 윈도우 배경도 포함 됩니다.

레이아웃에서 특별히 배경을 따로 주었다면 테마의 윈도우 배경은 android:background=”@null”을 주어 없애도록 합시다. 간혹 android:background=”@android:color/transparent”를 주는 경우가 있는데 눈에는 보이지 않지만 실제 내부적으로 draw하게 되니 @null로 주어 그려지지 않게합시다.

이렇게 가이드라인이 잘 지켜지고 있나 보기위해 몇개의 앱을 실행 해보았습니다.

구글에서 만든 앱인 구글 플레이와 구글 플레이어를 실행 해보았습니다. 빨강색은 거의 찾아 볼수 없을 정도로 최소한으로 그려지게 레이아웃을 구성 한것을 볼 수있습니다. 

해외 유명한 앱들도 테스트 해보면, 빨강색이 거의 찾아 볼 수 없을 정도로 최적화된 레이아웃을 구성하고 있습니다.

국내 유명한 앱들도 테스트를 해보니, 빨강색이 아닌 부분을 찾아 볼 수가 없습니다. 필요이상으로 draw되고 있다는 것을 보여주고 있습니다.

이런식으로 Over Draw가 되는 곳에는 레이아웃을 단순하게 정리해야 될 필요가 있다는 것을 확인 해보 실수 있습니다.

다음 시간에는 이런 Over Draw된 영역을 어떤식으로 최적의 레이아웃을 구성하는지에 대해 알아보겠습니다. 

<

p style=”text-align: left; clear: none; float: none; “> 

  




안드로이드 앱 성능 최적화 – 1. 즉각적인 반응을 위한 StrictMode 사용

안드로이드 플랫폼이 국내에 출시 된지도 약 3년이라는 시간이 지났습니다. 개발자들도 많은 경험이 축척되면서 앱의 퀄리티는 점점더 높아지고 있으나, 아직 해외 만큼의 퀄리티를 가진 국내앱은 손에 꼽힐 정도라고 생각합니다. 이런 퀄리티 높은 앱을 개발하기위해 좀 더 성능을 높이는 방법에 대해 소개 하기위해 “안드로이드 앱 성능 최적화”라는 주제를 가지고 연제글을 쓰게 되었습니다.

안드로이드앱 성능 최적화 – 1. 즉각적인 반응을 위한 StrictMode 사용

안드로이드앱 성능을 최적화 하는 방법중 첫번째 시간으로 사용자의 즉각적으로 반응을 보이기위해 도움을 줄 수있는 StrictMode에 대해서 이야기해보겠습니다.

안드로이드 앱을 사용 하면서 참 빠르다라는 것을 느끼게 되는것은 사용자의 이벤트에 대한 화면응답 속도가 빠른경우입니다. 

안드로이드 Main Thread(ui)에서 LifeCycle과 Linstener에 대한 Callback등을 처리 하고 있습니다. 

이렇게 Main Thread에서 오래 걸리는 작업(DB에 데이터 insert한다거나 네트워크를 통해 이미지를 불러온다거나)을 하게 된다면, 작업시 동안 아무런 화면에 반응이 없을 뿐더러, 최악의 경우 5초이상 걸리게 된다면 ANR발생으로 앱이 종료되어 버립니다.

Network Access나 파일 IO등에 대한 처리는 새로운 쓰레드에서 작업(AsyncTask, Loader)을 함으로써 이런 반응 속도에 대한 문제를 해결 할 수 있습니다.

하지만 개발자들은 이렇게 코드에 대한 응답 속도를 예측이 불가능 하기때문에, 새로운 쓰레드작업을 해야 할지 말아야 할지에 대해 선택이 어렵습니다.

이런 문제점을 해결 해줄수 있게 안드로이드 플랫폼에서는 StrictMode API를 제공하고 있습니다.

StrictMode는 Thread, VM에 관련된 정책을 만들 수 있으며, ThreadPolicy를 통해 특정 Thread 에 File I/O Netwrok Access 부분을 감지하여 위반되는 위치를 찾아주고 VmPolicy를 통해 메모리 Leak의 위치를 감지해 주는데 개발자가 이를 인지 할 수 있도록 Log, 강제 종료등 다양한 방법으로 알림을 제공합니다.

문제점이 있다면 Native에서 사용하는 File I/O, Network Access등에 대한 감지는 어렵습니다. 그리고 StrictMode는  API 9(2.3.3)부터 사용이 가능합니다.

StrictMode 사용으로 간단한 테스트를 해보겠습니다. 

package com.example.testapp;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Activate StrictMode
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll().penaltyLog().penaltyDeath().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
                .penaltyLog().penaltyDeath().build());

        setContentView(R.layout.activity_main);
        
        // Test code
        String eol = System.getProperty("line.separator");
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                    openFileOutput("myfile", MODE_WORLD_WRITEABLE)));
            writer.write("This is a test1." + eol);
            writer.write("This is a test2." + eol);
            writer.write("This is a test3." + eol);
            writer.write("This is a test4." + eol);
            writer.write("This is a test5." + eol);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Main Thread에서 File I/O작업을 하게 테스트코드를 만들었습니다. StrictMode에서는 이를 감지(긴 작업) 하며 강제적으로 앱을 종료하고 로그를 남기게 되었있습니다.

이렇게 LogCat에 위반된 로그를 남깁니다. StrictModeDiskViolation이라고 File I/O대한 문제라는 것을 알려 줍니다. 작업 시간이 114ms가 걸렸다는 것도 보실 수 있습니다. File I/O가 더 많이 일이나게 되면 시간이 훨씬 더 걸리므로 File I/O작업을  Main Thread가 아닌 새로운 Thread에서 작업을 하도록 구조를 바꾸면 됩니다. Loader나 AsyncTask, AsyncQueryHandler, HandlerThread등 안드로이드에서 제공하는 API는 많으니 활용하면 좋을것 같습니다.

안드로이드 API 12(4.0) 이상일때 아래와 다양한 API기능을 제공합니다.

CustomPolicy 

특정 소스 위치에 StrictMode.noteSlowCall(“CustomTest”)를 선언하고 Thread 정책에 detectCustomSlowCalls() 를 넣어주게 되면 StrictMode 에서 noteSlowCall() 이 선언된 부분을 모두 감지하고 penaltyXXX() 정책에 따라 개발자에게 알려주니 사용하시면 됩니다. 

PenaltyDeathOnNetwork() 

Main 쓰레드에서 Network Access 가 진행되면 무조건 어플리케이션이 강제 종료가 되도록 설정하는 것입니다.
이 기능은 detectNetwork() 정책이 활성화 되어 있을 때만 유효합니다.  

PenaltyFlashScreen() 

정책이 위반 됐을 때 화면상으로 아래와 같은 빨간 테두리의 사각형이 splash 로 보여줘 인지하기가 수월해 집니다. 특정 작업을 하는 동안 빨간 테두리가 오래 나타나게 된다면 그 부분의 로직은 수정되어야 할 부분입니다.

VM policy 

Activity 서브클래스의 leak 을 감지 해주는 detectActivityLeaks() 과
File/Network IO 관련 API 사용시 close() 를 명시적으로 호출 안하고 종료할 경우 나오는 리소스 leak 을 감지 해주는 detectLeakedClosableObjects() 와
특정 클래스가 어플리케이션 Heap 에 생성되는 최대 개수를 설정하여 object leak 현상을 모니터링 할 수 있도록 setClassInstanceLimit() 가 있습니다.

 

이렇게 StrictMode는 개발자가 작업데 대한 예측이 어려운 부분을 알려줌으로써 사용자 반응성에 즉각적인 응답을 할 수 있는 개발에 도움을 줄 수있습니다. 선택사항이긴하나 앱의 퀄리티를 높이기위해 필수사항이라고 생각되니 꼭 사용 하길 권해드립니다.

다음 시간은 Main Thread에서 구동되는 UI를 좀더 빠르게 그려지기위해 레이아웃 구조를 최적화를 확인 하는 방법과 이를 바탕으로 어떻게 최적화 해야 하는지에 대한 방법에 대해 이야기해보겠습니다.

[책리뷰]안드로이드 앱 성능 최적화








안드로이드 앱 성능 최적화

국내도서>컴퓨터/인터넷

저자 : Herve Guihot / 장독대역

출판 : 프리렉(이한디지털리) 2012.04.25
상세보기


 


안드로이드 앱 개발자로 일하면서 그동안 몰랐던 앱 성능을 최적화하기 위한 방법을 소개한 책이다.


 


ArrayList와 LinkedList의 사용범위에 따른 코드 최적화방법과 NDK를 이용한 좀더 빠른 앱을 개발하는 방법을 소개 해두었다.


또한 DB의 트렌젝션을 이용한 효율적인 DB쿼리 방법또한 좋았다.


 


그리고 모바일앱에서 가장중요한 메모리! 효율적으로 사용하는 방법과 가비지컬렉션과 메모리 누수와의 관계에 대해서도 참 잘설명 되어 있다.


 


레이아웃 최적화법및 툴을 이용한 최적화 방법, 벤치마크와 프로파일링에 대해 기술 해놓았다.


배터리 최대한 적게 사용하기등등 안드로이드 중급개발자들이 한번씩 읽어보면 좋을듯 하다.


 


요즘 폰들이 고사양이라 그 동안 막무간으로 사용해던 것에해대해 한번쯤 생각 해보고 돌이켜 볼 수 있는 안드로이드 앱 개발자라면 꼭 한번쯤은 읽어 봤으면 좋겠다.