본문 바로가기

모바일(Mobile)/안드로이드(Android)

[Android] 안드로이드란?, 안드로이드와 컴파일 (feat. DEX)

안드로이드란?

  • 안드로이드(Android)는 리눅스 커널을 기반으로 구글에서 만든 모바일 운영체제(OS)입니다.
  • 2008년 안드로이드 1.0을 첫 출시한 이후, 현 시점 모바일 OS에서 IOS와 경쟁하고 있는 OS입니다.

안드로이드의 특징

  • 공개 운영체제인 리눅스를 기반으로 합니다.
  • 또한, 안드로이드의 운영채제의 주요부분과 라이브러리 구글이 만든 앱 등의 코드는 대부분 공개되어 있습니다.
  • IOS와는 다르게 안드로이드 OS는 다양한 디바이스를 타겟으로 합니다. 따라서, 안드로이드 개발자는 다양한 안드로이드 디바이스에 대한 대응을 고려해야 합니다.
  • 안드로이드 플랫폼에서는 모든 응용 프로그램이 평등하다는 사상을 바탕으로, 모바일 디바이스에 설치된 앱과 개발자가 만든 앱은 동일한 API를 사용합니다.

안드로이드 운영체제의 구조

출처 : https://developer.android.com/guide/platform?hl=ko

 

안드로이드 운영체제는 위와 같은 아키텍처로 구성되어 있습니다. 이러한 구조 중에서 특별히 더 중요하게 알아두어야 할 부분은 다음의 세 가지입니다.

 

① 리눅스 커널
② 하드웨어 추상화 레이어(HAL, Hardware Abstract Layer)
③ 안드로이드 런타임(ART, Android Runtime)

안드로이드 소스코드의 컴파일 과정

  • 안드로이드는 컴파일 과정을 거쳐 최종적으로 DEX파일로 컴파일 됩니다.
  • 안드로이드 소스코드는 자바 또는 코틀린으로 작성되는데, 작성된 소스코드는 각 언어별 컴파일로를 통해 바이트 코드인 .class 파일로 컴파일됩니다.
  • 그후 .class파일은 .dex 확장자를 가지는 DEX 파일로 다시 한번 컴파일 됩니다.

💡 그래서 dex는 무엇일까?

  • dex는 구글에서 모바일 디바이스에서 사용하기 위해 만들었습니다.
  • dex는, Dalvik Executable의 약자이고, Dan Bornstein이 작성한 오픈 소스 소프트웨어입니다.
  • Dalvik이라는 이름은 아이슬란드의 작은 어촌마을인 Dalvík 에서 기원하였다고 합니다.

JVM vs DVM

안드로이드에 .dex가 사용되는 이유를 이해하려면, JVM과 DVM에대한 이해가 필요합니다.

먼저, JVM은 클래스가 필요할 때마다 동적으로 .class 파일을 읽습니다. 이 때 JVM은 컴퓨터의 메모리를 사용하게 되고 스택 기반으로 opcode(작업코드) 를 읽어서 사용합니다.
반면, DVM은 .dex라는 파일에 모든 클래스 파일들을 변환하여 저장합니다. 즉 하나의 파일에 모든 소스가 있는 셈입니다. 그리고 이러한 dex파일로부터 DVM은 opcode(작업코드) 를 읽어서 사용합니다.

정리하자면, JVM은 필요할 때마다 클래스 파일 중에서 골라 쓰는 셈이고, dex는 하나의 파일에서 관리한다는 것입니다.

그런데, 스택 기반의 가상머신은 컴퓨터의 메모리에서 스택으로 프로그램을 관리하는 반면, 레지스터 기반의 가상머신은 컴퓨터 CPU에 직접 접근하기 때문에 속도 측면에서 더 빠르나, CPU의 한정된 메모리를 사용하기 때문에 메모리 용량이 작다 는 단점이 있습니다.

메모리 용량 측면에서는 스택기반의 가상머신인 JVM이 유리하지만, 속도 측면에서는 레지스터 기반의 DVM이 유리한 것입니다.

왜 구글은 DVM을 채택했을까?

지금의 모바일 및 컴퓨터 하드웨어 기술 수준을 생각하면, 굳이 레지스터말고 자바 기반의 JVM을 사용해도 좋았을 것 같은데, 이 이유에 대해서 아직 안드로이드 스튜디오나 구글의 공식 입장을 찾아보진 못했습니다.

그러나, 제 스스로 그 이유를 추론해보자면 안드로이드 OS가 탄생했던 당시의 시대적 배경을 생각하면, 오히려 JVM 보다 DVM을 선택하는 것이 더 합리적이었다고 생각됩니다.

 왜냐하면, 초기 모바일 디바이스는 메모리 용량이 그렇게 크지도 않았고, 지금도 안드로이드 앱은 수많은 앱들이 하나의 디바이스에서 빠르게 상호작용하고 동작해야하는 점을 고려해보면, 클래스 로더로 .class 파일을 읽어 들여서 동작하는 JVM보다 컴파일 과정을 한번 더 거치더라도 DVM을 채택하면 빠른 속도도 취하고 안드로이드 앱의 라이프 사이클에 따른 빠른 자원의 관리도 유리한 것으로 보여 JVM보다 DVM이 더 합리적이었을 것 같다는 생각이 들었습니다.

 물론, 구글은 아마 이보다 더 많은 이유를 포함하여 OS를 설계하고 개발했겠지만, 제 스스로 찾아 보면서 생각해봤을 때는 이러한 이유로 구글이 JVM이 아닌 DVM을 선택했던 것이 더 합리적이라고 판단했을 것 같습니다.

dex를 사용함으로 인해서 발생한 문제점

이러한 안드로이드의 아키텍처에 따라서 모든 클래스 파일들은 최종적으로 .dex 로 컴파일이 됩니다.
그래서, 안드로이드 개발에서 자주 사용하는 jar 파일들은 어떻게 DVM에서 동작하게 되는지 의문이 생길 수 있습니다. 이는 jar 파일도 dx(Dexer) 를 통해 .dex파일로 컴파일되기 때문에 가능합니다. 그렇기에 dx(Dexer)는 안드로이드의 SDK(Software Develop Kit) 의 표준 구성 요소가 되었습니다.

하지만, dex는 앞서 설명한 구조적 한계 때문에 다음과 같은 이슈가 있습니다.

  1. ANR(애플리케이션 응답 없음)의 발생, 즉 너무 큰 .dex 파일을 읽어들임으로 인해 애플리케이션이 일시적으로 중단되는 것입니다.
  2. multidex 기반 애플리케이션은 Android 4.0(API 레벨 14) 미만의 시스템에서는 정상적으로 작동하지 않을 수 있습니다.

참고하면 좋을 사이트 : https://www.boldare.com/blog/differences-between-class-and-dex-files-in-java-android/

안드로이드 개발 도구

  • 대부분의 안드로이드 앱은 Java로 만든 API를 통해서 개발을 하게 됩니다.
  • 그러나, 안드로이드 앱은 C나 C++로 개발된 네이티브 라이브러리도 사용할 수 있는데, 이를 안드로이드 NDK(Native Development Kit) 라고 합니다.
  • 자바로 만든 라이브러리들은 자바 API 프레임워크 라고 부릅니다.

안드로이드 API LEVELs

API LEVEL 버전 명(코드 네임) 출시연도
1 Android 1.0 2008
2 Android 1.1 2009
3 Android 1.5 (컵케이크) 2009
4 Android 1.6 (도넛) 2009
5 Android 2.0 (에클레어) 2009
6 Android 2.0.1 2009
7 Android 2.1 (에클레어) 2010
8 Android 2.2 (프로요) 2010
9 Android 2.3 (진저브레드) 2010
10 Android 2.3.3 2011
11 Android 3.0 (허니콤) 2011
12 Android 3.1 2011
13 Android 3.2 2011
14 Android 4.0 (아이스크림 샌드위치) 2011
15 Android 4.0.3 2011
16 Android 4.1 (젤리빈) 2012
17 Android 4.2 2012
18 Android 4.3 2013
19 Android 4.4 (킷캣) 2013
20 Android 4.4W 2014
21 Android 5.0 (롤리팝) 2014
22 Android 5.1 2015
23 Android 6.0 (마시멜로) 2015
24 Android 7.0 (누가) 2016
25 Android 7.1 2016
26 Android 8.0 (오레오) 2017
27 Android 8.1 2017
28 Android 9.0 (파이) 2018
29 Android 10.0 (Q) 2019
30 Android 11.0 2020
31 Android 12.0 2021
32 Android 12.1 2022
33 Android 13 2022
34 Android 14 DEV TBD