안드로이드 2.2 버전 업데이트에서 변경된 사항 중 가장 특이할 만한 점은 역시 어플리케이션을 외부 메모리에 설치할 수 있는 기능이 추가된 점을 들 수 있습니다. 한동안 인터넷을 뜨겁게 달구었던, 안드로이드 메모리 문제 해결을 위한 서광이 비춘 셈이라고 할 수 있겠네요. 그런데 생각보다 제약 사항이 좀 있네요. 어플리케이션 개발할 때 여러모로 신경써야할 필요가 있어 보입니다. 실제로 개발자들이 어떻게, 자신의 어플리케이션을 외부 저장 장치에 설치 할 수 있도록 만들 수 있는지에 관한 문서가 업데이트되어 번역해 봅니다.

Android App Install Location

원본:http://developer.android.com/guide/appendix/install-location.html


 API Level 8(Android 2.2) 을 시작으로, 마침내 개발자는 자신의 어플리케이션이 SD 카드와 같은 외부 저장 장치에 설치되도록 설정 할 수 있게 되었다. 이 기능은 하나의 추가적인 옵션으로, 안드로이드 메니페스트 파일에 android:installLocation 속성을 이용해서 적절한 값을 설정할 수 있다. 만일 개발자가 이 속성을 선언하지 않는 경우, 기본적으로 어플리케이션은 내장 메모리에만 설치되며, 사용자들은 해당 어플리케이션을 외부 저장장치로 옮길 수 없다.

 시스템이 개발자의 어플리케이션을 외부 저장 장치에 설치할 수 있도록 허용하기 위해서는, 안드로이드메니페스트 파일의 <manifest> 엘레먼트에 "preferExternal" 혹은 "auto" 값을 갖는 android:installLocation 속성 값을 추가해야 한다. 예를 들자면 다음과 같다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   
android:installLocation="preferExternal"
    ...
>

 만일 개발자가, "preferExternal" 이라고 속성값을 설정하면 해당 어플리케이션을 외부 저장장치에 설치해 달라고 요청하는 셈이다. 하지만 해당 어플리케이션이 반드시 외부 저장장치에 설치될 것이라고 보장되지는 않는다. 만일 외부 저장장치에 빈 공간이 없다면, 해당 어플리케이션은 내부 메모리에 설치된다. 또한, 이 속성 값이 설정되는 경우, 폰 사용자는 이미 설치된 어플리케이션의 위치를 내부/외부 메모리로 자유롭게 옮길 수 있다. 

 만일 개발자가 "auto" 값을 선언한다면, 시스템은 몇 가지 요소를 기반으로 해당 어플리케이션을 어디에 설치할 지 알아서 결정한다. 물론 사용자는 설치된 어플리케이션을 내부/외부 메모리로 자유롭게 옮길 수 있다. 

어플리케이션이 외부 저장 장치에 설치된다면 다음과 같은 특징을 갖는다.
  •  외부 저장 장치가 마운트 되어 있는 한, 어플리케이션 성능 상에 어떠한 차이점도 없다. 
  •  어플리케이션 .apk 파일은 외부 저장 장치에 저장된다. 하지만 모든 private 한 사용자 데이터와, 데이타 베이스, 최적화된 .dex 파일과 native 코드들은 모두 내부 메모리에 저장된다. 
  • 개발자의 어플리케이션이 저장된 유니크한 컨테이너는 랜덤하게 생성된 키를 이용해서 암호화되며, 해당 어플리케이션을 설치한 디바이스만이 암호를 풀 수 있다. 그러므로, SD 카드에 설치된 어플리케이션은 오직 하나의 디바이스에서만 작동한다.
  • 사용자는 시스템 설정을 통해서, 외부 저장 장치에 설치된 어플리케이션을 내부 메모리로 옮길 수 있다.
01

Backward Compatibility

하위 호환성

 어플리케이션을 외부 메모리에 설치하는 기능은 오직 안드로이드 버전 2.2 이상의 기기에서만 가능하다. API Level 8 이전 버전으로 작성된 어플리케이션은 항상 내부 메모리에 저장되며, 외부 메모리로 옮길 수 없다. (사용자가 2.2 이상의 디바이스를 사용하더라도.) 하지만, 반대로 만일 개발자가 API Level 8 이상의 버전으로 어플리케이션을 작성하며 해당 기능을 사용하면서 동시에, 이전 버전의 디바이스와의 호환성을 유지하는 것은 가능하다.

이를 위해서는 다음과 같은 작업이 필요하다. 
  1. <manifest> 엘리먼트에 android:installLocation 속성을 추가한다. 
  2. android:minSdkVersion 속성 값을 8 이 아닌 그 보다 작은 값으로 설정한다. 어플리케이션 코드는 설정된 버전가 호환가능한 API 만을 사용해야 한다. 
  3. 어플리케이션을 컴파일 하기 위해, 어플리케이션 빌드 타겟을 API Level 8 로 변경하라.왜냐하면 이전 버전의 안드로이드 라이브러는 해당 속성 값에 관해 알지 못하고, 따라서 컴파일이 실패하기 때문이다. 
  4. 여러분의 어플리케이션이 2.2 이전 버전에 설치될 때, 메니페스트의 android:installLocation 속성 값은 무시되고, 어플리케이션은 내부 메모리에 설치될 것이다.

Applications That Should NOT Install on External Storage

외부 저장 장치에 설치되어서는 않되는 어플리케이션.

 사용자가 컴퓨터와 USB 대용량 저장 장치 모드로 연결하거나, 외부 메모리를 언 마운트 하는 경우, 외부 메모리에 설치되어 있는 어플리케이션은 모두 종료된다. 또한 시스템은 해당 어플리케이션에 대해 외부 저장 장치가 다시 마운트 되기 전 까지는 알 수 없다. 게다가 어플리케이션을 종료하고 사용자가 해당 어플리케이션을 사용할 수 없게 만드는 것은 특정한 어플리케이션에 있어서는 심각한 오류를 발생 시킬 수 있다. 어플리케이션이 기대한 대로 일관되게 작동하게 만들기 위해서는, 개발자는 자신의 어플리케이션의 아래 나열된 기능들을 사용하는 경우, 외부 저장 장치에 설치될 수 없도록 만들어야 한다. 

Services
작동하고있는 서비스는 종료된 후 외부 저장 장치가 재 마운트 되더라도 재시작되지 않는다. 개발자가 ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 브로드케스트 인텐트 리시버를 등록하고, 개발자의 어플리케이션이 다시 사용 가능해진 시점에 서비스를 다시 시작하도록 구현 한다면 가능하다.
Alarm Services
 AlarmManager 에 등록해두었던 Alarm 들은 모두 취소 된다.외부 저장 장치가 다시 마운트 되었을 때, 일일히 필요한 Alarm 을 재등록 해 주어야 한다.
Input Method Engines(IME)
개발자가 작성한 IME 는 기본 IME 로 대체된다. 외부 저장 장치가 다시 마운트 된 후에는, 사용자가 시스템 설정에서 개발자의 IME 를 다시 활성화 시켜야 한다.
Live Wallpapers
개발자가 작성한 Live Wallpaper 는 기본 Live Wallpaper 로 변경된다. 
외부 저장 장치가 다시 마운트 된 후에는, 사용자가 기존 Live Wallpaper 를 다시 선택해야 한다. 
Live Folders
개발자가 작성한 Live Folder 가 홈스크린에서 사라진다. 외
부 저장 장치가 다시 마운트 된 후에는, 사용자가 해당 Live Folder 를 다시 추가 할 수 있다. 
App Widgets
개발자가 작성한 App Widget 은 홈스크린에서 사라진다. 외부 저장 장치가 다시 마운트 된 후에도 해당 App Widget 은 사용 할 수 없다. 삭제된 App Widget 은 홈 어플리케이션이 재 시작되어야지만 사용가능하다. (일반적으로 시스템이 재부팅 되기전에는 일어나지 않는 일이다.)
Account Managers
외부 저장 장치가 다시 마운트 되기 전 까지, 해당 어플리케이션을 통해 생성된 사용자 계정 정보가 사라진다.
Sync Adapters
개발자의  AbstractThreadedSyncAdapter 및 모든 동기화 기능들은 외부 저장 장치가 다시 마운트 되기 전 까지 작동하지 않는다. 
Device Administrators
개발자의 DeviceAdminReceiver 및 모든 어드민 기능들은 작동 불가 상태가 되며, 디바이스의 기능에 있어서 예측할 수 없는 문제를 야기할 수 있다. 또한 이러한 문제는 외부 저장 장치가 다시 마운트 된 후에도 영구적으로 이어질 수 있다. (주> 무섭네요;;;;)

 만일 개발자의 어플리케이션이 위 목록에 나온 기능 중에 한 가지라도 사용하고 있다면, 해당 어플리케이션은 외부 저장 장치에 설치되어서는 않된다. 기본적으로 시스템은 어플리케이션이 외부 저장 장치에 설치되는 것을 허용하지 않기 때문에, 기존에 작성했던 어플리케이션에 대해서는 걱정할 필요가 없다. 하지만, 만일 개발자가 자신의 어플리케이션이 반드시 '내부 메모리' 에 설치되어야 할 것을 명시하고자 한다면, android:installLocation 항목에 "internalOnly" 값을 설정할 수 있다. 비록 이렇게 값을 설정한다고 시스템의 기본적인 행동이 변하는 것은 아니지만, 명시적으로 해당 어플리케이션의 설치 경로를 선언함으로서, 어플리케이션이 내부 메모리에 설치되어야 한다는 사실을 개발자 본인이나 다른 개발자들에게 환기 시킬 수 있다. 

Applications That Should Install on External Storage

외부 저장 장치에 설치되어야 하는 어플리케이션

 간단히 말해, 이전에 나열된 기능을 사용하지 않는 모든 어플리케이션은 외부 저장 장치에 설치되어도 안전하다. 게임은 대게, 활성화 되어있지 않은 상황에는 별다른 서비스를 제공하지 않기 때문에, 용량이 큰 게임들은 일반적으로 외부 저장 장치에 설치되도록 허용되어야 한다.  외부 저장 장치가 언마운트되어서 게임 프로세스가 종료되었다고, 이 후에 다시 마운트 되어 사용자가 게임을 재시작하는 경우를 생각해 보면, 게임이 일반적인 Activity 라이프 사이클에 따라 상태 정보를 잘 저장해 둔 한, 사용자에게 별다른 영향을 끼지치 않을 것이다.

 만일 개발자의 어플리케이션이 수메가의 용량을 필요로 한다면, 개발자는 사용자들이 내부 메모리 공간을 절약할 수 있도록, 해당 어플리케이션이 외부 저장 장치에 설치될 수 있도록 허용할 것인가에 관해 심각하게 고민해 보아야 한다.