brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Apr 17. 2017

Reduce APK

Smaller APKs : A checklist

Reduce APK


APK 크기가 커지면 앱을 다운로드하고 설치하는 시간이 오래 걸리고 네트워크 소모량도 많아집니다.

뿐만 아니라 앱의 실행 속도, 사용되는 메모리 용량, 소비 전력에도 영향을 줍니다.


일반적으로 APK 크기를 줄이려면 리소스와 코드를 줄여야 합니다.

이를 위한 몇 가지 방법을 정리했습니다.




Understand the APK Structure


우선 APK 구조를 알아봅시다.

APK 파일은 앱을 구성하는 모든 파일을 포함하는 ZIP 아카이브로 구성됩니다.


META-INF/

CERT.SF, CERT.RSA 서명 파일과 MANIFEST.MF 매니패스트 파일을 포함하는 디렉터리
 - MANIFEST.MF : 매니페스트 파일 (en:Manifest file).
 - CERT.RSA : 응용 프로그램에 대한 전자 서명 파일.
 - CERT.SF : 매니페스트 파일을 포함한 리소스와 그에 대응하는 SHA-1 해시값.


assets/

AssetManager를 통해 검색할 수 있는, 응용 프로그램의 정보를 포함하는 디렉터리


res/

resources.arsc에서 제외된 정보를 포함하는 디렉터리


lib/

프로세스와 연계된 소프트웨어 레이어를 포함하는 디렉터리
- armeabi  : ARM 기반 프로세서 전용으로 컴파일된 코드.
- armeabi-v7a : ARMv7와 그것을 기반으로 하는 프로세서 전용으로 컴파일된 코드.
- x86  : x86 기반 프로세서 전용으로 컴파일된 코드.
- mips  : MIPS 기반 프로세서 전용으로 컴파일된 코드.


resources.arsc

이진 XML과 같은 선컴파일된 리소스를 포함하는 파일.
이 파일에는 res / values / 폴더의 모든 구성에서 XML 내용이 들어 있습니다. 패키징 도구는 이 XML 내용을 추출하여 이를 이진 형식으로 컴파일하고 내용을 보관합니다. 이 컨텐트에는 언어 문자열 및 스타일뿐만 아니라 레이아웃 파일 및 이미지와 같이 resources.arsc 파일에 직접 포함되지 않은 컨텐트 경로가 포함됩니다.


classes.dex

Dalvik/ART 가상 머신에 의해 dex 파일 형식으로 컴파일된 영역.


AndroidManifest.xml

Core 안드로이드 매니페스트를 포함하는 파일
추가적인 매니페스트 파일. 응용 프로그램의 이름, 버전, 액세스 권한, 라이브러리 파일을 정보를 포함한다. 이 파일은 안드로이드의 바이너리 XML 포맷을 이용합니다.





Reduce Resource Count and Size


#01 Remove Unused Resources


#01 build.gradle


Gradle은 앱의 build.gradle 파일에서 shrinkResources를 사용하도록 true로 설정하면 자동으로 리소스를 삭제할 수 있습니다. (코드 축소의 경우 minifyEnabled도 true로 설정)





#02 Support Only Specific Densities


#02 Multiple resolutions


안드로이드는 다양한 화면 밀도와 해상도를 지원합니다.

특히 Android 4.4부터는 프레임 워크가 다양한 밀도 (ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi 및 xxxhdpi)를 지원하는데, 이러한 모든 밀도를 지원하기 위해 각각의 리소스를 다 가지고 있을 필요는 없습니다.


#03 Scaled resources


만약 특정 밀도에 대한 리소스가 없다면 안드로이드는 다른 밀도의 리소스를 가져와 크기를 알아서 재조정하기 때문입니다. 따라서 재조정한 리소스가 큰 문제가 없다면 화면 밀도 모두에 대응하지 않아도 됩니다.

res/drawable-nodpi/
이 폴더에 리소스를 넣으면 화면 밀도에 따라 크기를 재조정하지 않습니다.





#03 Use Vector drawable Objects


#04 Same simple images


Android 5.0에서 이용 가능한 VectorDrawable은 색상 정보와 함께 점, 선 및 곡선 집합으로 XML 파일에 정의된 벡터 그래픽입니다.

크고 복잡한 이미지도 표현 가능 하지만 렌더링하고 화면에 표시하는데 오래 걸리기 때문에 작고 단순한 이미지의 경우 PNG나 JPEG 대신 Vector drawable을 이용할 수 있습니다.


비트맵 이미지의 경우 각 화면 밀도마다 리소스가 필요한 반면, 벡터 이미지의 경우에는 하나의 파일로 모든 화면 밀도에 대응할 수 있습니다.


#05 Only one vector drawable


http://pluu.github.io/blog/android/2016/04/11/android-vector/




#04 Reuse Resources


같은 이미지의 색조, 음영 또는 회전 같은 이미지의 변형에 대해 별도의 리소스를 포함할 수 있습니다.

그러나 동일한 리소스 집합을 재사용하고 런타임에 필요에 따라 지정하는 것이 좋습니다.


예를 들어 서로의 회전 인 두 개의 이미지가 있다고 가정해 보면,

레이아웃 코드에서 아래와 같이 단순히 이미지를 회전시켜 기존 이미지를 재사용할 수 있습니다.


#06 Reuse resources




Reduce Code


#01 Remove Unused Codes


사실 코드는 이미지 리소스에 비해 큰 문제가 되지는 않지만 64K 메서드 제한 문제도 해결할 수 있기에 살펴봐야 합니다.


우선 리소스와 마찬가지로  ProGuard로 코드 축소를 활성화하려면 gradle 설정에서 minified enabled true로 설정해야 합니다. 이렇게 하면 사용하지 않는 코드들은 알아서 제거가 됩니다.


#07 build.gradle





#02 Avoid Unnecessary Libraries


#08 Third party library


Third party(외부) 라이브러리를 잘 살펴봐야 합니다.

일부 라이브러리, 특히 서버 또는 데스크톱 환경을 위해 설계된 라이브러리에는 안드로이드에서 필요로 하지 않는 수많은 코드들이 있을 수 있습니다.

보통 ProGuard를 통해 난독화하는 과정에서 필요 없는 코드를 빼고 APK를 만들 수 있지만, 일부 코드는 내부의 복잡한 종속성으로 인해 제한을 받을 수 있습니다.

따라서 이런 부분이 많은 큰 규모의 라이브러리들은 ProGuard 만으로는 해결할 수 없습니다.


따라서 안드로이드에 최적화된 라이브러리들을 찾아 이용하거나 만약 찾을 수 없다면 해당 라이브러리에서 필요한 기능만 추출하거나 수정해야 합니다.




#03 Multiple APKs


#09


일부 OS 버전이나 해상도 같이, 특정 타깃을 대상에만 필요한 리소스나 코드가 필요한 경우가 있습니다.

빌드와 배포의 편의성 때문에 하나의 앱에서 다 처리할 수 있지만 사용자 입장에서는 자신의 기기에 필요 없는 리소스들로 인해 앱을 다운로드하고 설치하는데 많은 시간과 자원을 소모해야 합니다.


이를 해결하기 위해 구글 플레이에서는 Multiple APK라는 다양한 환경에 따라 여러 개의 APK를 배포할 수 있는 서비스를 제공하고 있습니다.









APK 크기를 줄이기 위해 신경 쓸 부분이 많은데, 기능 구현하고 버그 잡기 바쁜 와중에 신경 쓰기가 사실 귀찮은 일이기도 합니다.

하지만 단순히 크기를 줄이는데 그치지 않고 앱의 퍼포먼스를 높이고 멀티 덱스 문제도 해결할 수 있기에 신경 써서 줄여봅시다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari