정보공간_1

[4기 신촌 박영웅] Android Application Stealth Update (1) 본문

IT 놀이터/Elite Member Tech & Talk

[4기 신촌 박영웅] Android Application Stealth Update (1)

알 수 없는 사용자 2013. 11. 5. 17:03

안녕하세요 신촌멤버십 22-2기 박영웅입니다.

저는 Android Application의 Stealth Update 구현과 관련된 내용을 설명드리려합니다.



우선 일반적인 Android Application의 업데이트 방식부터 알아볼까요?


업데이트는 어플리케이션에서 기능 개선 혹은 오류 수정을 위하여

개발 주체가 어플리케이션의 변경된 일부분 혹은 전체를 교체하는 방식으로 이루어집니다.



[그림1] 변경 사항만 교체하는 업데이트 방식의 경우

 


일반적으로 PC 환경에서 동작하는 어플리케이션의 경우

[그림1]과 같이 기존에 설치된 프로그램을 자동으로 검색하여 필요한 내용을 바꿔주는 방식을 취합니다.



[그림2] 전체를 재설치하는 업데이트 방식 

 


하지만 우리가 현재 주로 사용하고 있는 안드로이드 스마트폰 어플리케이션의 경우

[그림2]와 같이 변경점을 교체하는 방식이 아닌

변경된 전체 어플리케이션을 재설치하는 방식으로 이루어집니다.


사용자 관점에서는 일부분을 교체하든 전체를 재설치하든 표면적으로는

단일한 파일을 통해 설치 과정을 수행한다는 관점에서는 동일해 보일 수 있습니다.


하지만 교체가 필요한 부분만을 교체하는 것이 아닌 전체를 재설치하는 방식의 경우

해당 설치 파일을 다운로드 받는 과정에서 발생하는 시간과 데이터 사용량의 증가를 초래하기 때문에

사용자에게 좋지 못한 방법입니다.



게다가 대다수의 사용자들이 특정한 어플리케이션 마켓 플레이스,

예를들어 각 이동통신사 마켓, Google Play Store, Samsung Apps과 같은 경로를 통하여

어플리케이션을 설치하고 업데이트를 하기 때문에

이 과정에서 해당 마켓 플레이스의 양식에 맞게 어플리케이션을 수정하여 업로드하는 과정이 필요합니다.


일부 마켓 플레이스의 경우 일정한 정책을 가지고 어플리케이션을 검수하는 곳도 있기 때문에

개발 주체가 어플리케이션 업데이트를 위한 과정을 마친 후에도

실제 어플리케이션 사용자들이 업데이트를 할 수 있기까지 일정 시간이 소요됩니다.


때문에 안드로이드 어플리케이션의 잦은 업데이트는

개발 주체와 사용자 모두에게 불편을 초래하며 어플리케이션 자체의 신뢰성을 떨어뜨리는 주요 원인이 됩니다.

이러한 문제점 때문에 오류를 발견했음에도 불구하고 업데이트를 꺼리는 경우도 있는 실정입니다.



그렇다면 이러한 단점을 어떻게 극복할 수 있을까요?


[그림3] the components involved in building and running an application

(http://developer.android.com/tools/building/index.html)



안드로이드 어플리케이션 [그림3]과 같은 과정을 거쳐 만들어져 동작하게됩니다.

일반적인 안드로이드 어플리케이션의 경우 해당 APK 내classes.dex 파일의 클래스 정보를 로드합니다.



하지만,


Run-time Dynamic Class Loading 기법을 활용하면

Load-time이 아닌 Run-time에 특정 클래스에 대한 접근이 가능해집니다.

때문에 안드로이드 패키지 파일(APK) 내에 포함되어있지 않은 클래스에 대한 접근이 가능해지는 것이지요.


이 기법을 활용하기 위해서는 어플리케이션을 설계할 때 동적으로 로드할 클래스명을 미리 고려하여

이에 맞는 클래스를 로드하는 부분과 이를 업데이트하는 부분만 어플리케이션에 포함하여 배포합니다.

이후 어플리케이션에서 로드하는 클래스는 서버를 통하여 배포하는 방식을 활용한다면

마켓 플레이스를 통한 업데이트가 아닌 스텔스 업데이트(Stealth Update)가 가능해집니다.



Java에서는 java.lang.ClassLoader를 통하여 JVM(Java Virtual Machine) 상에 클래스를

Run-time에 로드하는 기능을 지원합니다.


Android의 경우 JVM이 아닌 Dalvik Virtual Machine 상에서 동작하기 때문에

이것을 사용하여 위의 기법을 구사할 수 없습니다.


하지만 기능적으로 동일하게 동작하는 dalvik.system.DexClassLoader를 사용한다면

Java에서와 동일한 형태로 Run-time Dynamic Class Loading 기법을 사용할 수 있습니다.


실제로 Java의 java.lang.ClassLoader의 경우

Java 코드를 컴파일하여 생성된 .class 파일을 로드하며,

Android의 dalvik.system.DexClassLoader는 .class 파일이 아닌

.jar 파일 혹은 .apk 파일이 포함하고 있는

classes.dex(Dalvik Executable Format) 파일을 로드하도록 정의되어 있습니다.




그렇다면 이제 DexClassLoader에 대해 알아볼까요?

DexClassLoader의 생성자는 다음과 같습니다.


[그림4] DexClassLoader Summary 

(http://developer.android.com/reference/dalvik/system/DexClassLoader.html)



생성자의 인자는 각각 다음을 의미하며 4번째 인자는 Nullable합니다.

  1. 로드하려는 classes.dex가 포함되어있는 .jar 파일 혹은 .apk 파일의 경로 리스트
  2. 첫 번째 인자로 받은 대상 파일을 최적화한 것을 임시 저장해 둘 경로
  3. 네이티브 라이브러리를 포함하는 디렉토리 경로 리스트
  4. 부모 클래스로더


이제 DexClassLoader를 통해 Run-time에서 동적인 클래스 로드가 가능해졌습니다.

제가 앞서 java.lang.ClassLoader와 dalvik.system.DexClassLoader가 기능적으로 동일하게 동작한다고

말씀드렸던 것처럼 DexClassLoader를 생성한 후의 사용법은 java.lang.ClassLoader의 사용법과 같습니다.


하지만 이에 대한 사용법이 궁금하신 분들을 위하여,

다음 글에 이어 DexClassLoader의 사용법을 더 상세히 알아보도록 하겠습니다.