앱 리소스 개요

리소스는 코드에서 사용하는 추가 파일과 정적인 콘텐츠입니다. 예를 들어 비트맵, 레이아웃 정의, 사용자 인터페이스 문자열, 애니메이션 지침 등이 있습니다.

이미지나 문자열과 같은 앱 리소스는 항상 코드로부터 외부화합니다. 그래야 이들을 독립적으로 유지관리할 수 있습니다. 또한 특별히 이름이 지정된 리소스 디렉터리에 그룹화하여 특정 기기 구성에 관한 대체 리소스를 제공합니다. Android는 런타임에 현재 구성을 근거로 적절한 리소스를 사용합니다. 예를 들어 화면 크기에 따라 다른 UI 레이아웃을 제공하거나 언어 설정에 따라 다른 문자열을 제공할 수 있습니다.

앱 리소스를 외부화하면 프로젝트 R 클래스에서 생성되는 리소스 ID로 액세스할 수 있습니다. 이 문서에서는 Android 프로젝트에서 리소스를 그룹화하는 방법을 보여줍니다. 또한 특정 기기 구성에 관한 대체 리소스를 제공한 다음 앱 코드나 다른 XML 파일에서 액세스하는 방법도 보여줍니다.

그룹 리소스 유형

프로젝트의 res/ 디렉터리에 있는 특정 하위 디렉터리에 각 유형의 리소스를 배치합니다. 간단한 프로젝트에서 볼 수 있는 파일 계층 구조의 예는 다음과 같습니다.

MyProject/
    src/
        MyActivity.java
    res/
        drawable/
            graphic.png
        layout/
            main.xml
            info.xml
        mipmap/
            icon.png
        values/
            strings.xml

res/ 디렉터리에는 하위 디렉터리의 모든 리소스(이미지 리소스 1개, 레이아웃 리소스 2개, 런처 아이콘의 mipmap/ 디렉터리 1개, 문자열 리소스 파일 1개)가 포함되어 있습니다. 리소스 디렉터리 이름은 중요하며 표 1에 설명되어 있습니다.

참고: 밉맵 폴더 사용에 관한 자세한 내용은 밉맵 디렉터리에 앱 아이콘 배치를 참고하세요.

표 1. 프로젝트 res/ 디렉터리 내부에서 지원되는 리소스 디렉터리

디렉터리 리소스 유형
animator/ 속성 애니메이션을 정의하는 XML 파일입니다.
anim/ 트윈 애니메이션을 정의하는 XML 파일입니다. 속성 애니메이션도 이 디렉터리에 저장할 수 있지만 두 가지 유형을 구분하기 위해 속성 애니메이션은 animator/ 디렉터리에 저장하는 것이 좋습니다.
color/ 색상의 상태 목록을 정의하는 XML 파일입니다. 자세한 내용은 색상 상태 목록 리소스를 참고하세요.
drawable/

다음 드로어블 리소스 하위유형으로 컴파일되는 비트맵 파일(PNG, .9.png, JPG 또는 GIF) 또는 XML 파일입니다.

  • 비트맵 파일
  • 나인-패치(크기 조절이 가능한 비트맵)
  • 상태 목록
  • 도형
  • 애니메이션 드로어블
  • 기타 드로어블

자세한 내용은 드로어블 리소스를 참고하세요.

mipmap/ 다양한 런처 아이콘 밀도에 관한 드로어블 파일입니다. mipmap/ 폴더로 런처 아이콘을 관리하는 방법에 관한 자세한 내용은 밉맵 디렉터리에 앱 아이콘 배치를 참고하세요.
layout/ 사용자 인터페이스 레이아웃을 정의하는 XML 파일입니다. 자세한 내용은 레이아웃 리소스를 참고하세요.
menu/ 옵션 메뉴, 컨텍스트 메뉴 또는 하위 메뉴 등의 앱 메뉴를 정의하는 XML 파일입니다. 자세한 내용은 메뉴 리소스를 참고하세요.
raw/

원시 형태로 저장하기 위한 임의의 파일입니다. 원시 InputStream으로 이러한 리소스를 열려면 리소스 ID(R.raw.filename)를 사용하여 Resources.openRawResource()를 호출합니다.

그러나 원래 파일 이름과 파일 계층 구조에 액세스해야 한다면 res/raw/ 대신 assets/ 디렉터리에 리소스를 저장해 보세요. assets/의 파일에는 리소스 ID가 부여되지 않으므로 AssetManager를 사용해서만 읽을 수 있습니다.

values/

문자열과 정수, 색상 등 간단한 값을 포함하는 XML 파일입니다.

다른 res/ 하위 디렉터리에 있는 XML 리소스 파일은 XML 파일 이름을 근거로 하나의 리소스를 정의하는 반면, values/ 디렉터리에 있는 파일은 여러 개의 리소스를 설명합니다. 이 디렉터리에 있는 파일의 경우, <resources> 요소의 각 하위 요소가 하나의 리소스를 정의합니다. 예를 들어 <string> 요소는 R.string 리소스를 생성하고 <color> 요소는 R.color 리소스를 생성합니다.

각 리소스가 자체 XML 요소로 정의되므로 파일 이름을 원하는 대로 지정하고 하나의 파일에 여러 리소스 유형을 넣을 수 있습니다. 그렇지만 명확하게 하려면 고유한 리소스 유형을 서로 다른 파일에 배치하는 것이 좋습니다. 예를 들어 이 디렉터리에 만들 수 있는 리소스에 관한 몇 가지 파일 이름 규칙은 다음과 같습니다.

자세한 내용은 문자열 리소스, 스타일 리소스, 리소스 유형 더보기를 참고하세요.

xml/ Resources.getXML()을 호출하여 런타임에 읽을 수 있는 임의의 XML 파일입니다. 검색 구성 등 다양한 XML 구성 파일을 여기에 저장해야 합니다.
font/ TTF, OTF 또는 TTC와 같은 확장자가 있는 글꼴 파일 또는 <font-family> 요소를 포함하는 XML 파일입니다. 글꼴을 리소스로 사용하는 방법에 관한 자세한 내용은 글꼴을 XML 리소스로 추가를 참고하세요.

주의: res/ 디렉터리 내에 직접 리소스 파일을 저장하면 안 됩니다. 컴파일러 오류가 발생합니다.

개별 리소스 유형에 관한 자세한 내용은 리소스 유형 개요를 참고하세요.

표 1에 정의된 하위 디렉터리에 저장하는 리소스가 기본 리소스입니다. 즉, 이러한 리소스는 앱의 기본 디자인과 콘텐츠를 정의합니다. 그러나 다양한 유형의 Android 지원 기기에는 여러 유형의 리소스가 필요할 수 있습니다.

예를 들어 일반 크기보다 큰 화면이 적용되어 추가 화면 공간을 활용하는 기기에 다른 레이아웃 리소스를 제공할 수 있습니다. 기기의 언어 설정에 따라 사용자 인터페이스의 텍스트를 번역하는 다양한 문자열 리소스를 제공할 수도 있습니다. 다양한 기기 구성에 서로 다른 리소스를 제공하려면 기본 리소스 이외에 대체 리소스를 제공해야 합니다.

대체 리소스 제공

대부분의 앱은 특정 기기 구성을 지원하는 대체 리소스를 제공합니다. 예를 들어 다양한 화면 밀도용 대체 드로어블 리소스와 다양한 언어용 대체 문자열 리소스를 포함합니다. Android는 런타임에 현재 기기 구성을 감지하고 앱의 적절한 리소스를 로드합니다.

그림 1. 화면 크기에 따라 다른 레이아웃 리소스를 사용하는 기기 2대

리소스 집합의 구성별 대체를 지정하려면 다음 단계를 따르세요.

  1. res/<resources_name>-<qualifier> 형식으로 이름을 지정하여 새 디렉터리를 만듭니다.
    • <resources_name>은 해당 기본 리소스의 디렉터리 이름입니다(표 1에 정의되어 있음).
    • <qualifier>는 리소스를 사용할 개별 구성을 지정하는 이름입니다(표 2에 정의되어 있음).

    2개 이상의 <qualifier>를 추가할 수 있습니다. 대시로 구분하면 됩니다.

    주의: 여러 한정자를 추가할 때는 표 2에 표시된 순서와 동일하게 배치해야 합니다. 한정자의 순서가 잘못되면 리소스가 무시됩니다.

  2. 적절한 대체 리소스를 이 새 디렉터리에 저장하세요. 리소스 파일에 기본 리소스 파일과 정확히 동일한 이름을 지정해야 합니다.

예를 들어 몇 가지 기본 리소스 및 대체 리소스는 다음과 같습니다.

res/
    drawable/
        icon.png
        background.png
    drawable-hdpi/
        icon.png
        background.png

hdpi 한정자는 해당 디렉터리의 리소스가 고밀도 화면 기기용이라는 것을 나타냅니다. 이러한 드로어블 디렉터리에 있는 이미지는 특정 화면 밀도에 맞춰 크기가 조절되지만 파일 이름은 정확히 같습니다. 이렇게 하면 icon.png 또는 background.png 이미지를 참조하는 데 사용하는 리소스 ID가 항상 동일합니다. Android는 리소스 디렉터리 이름의 한정자와 기기 구성 정보를 비교하여 현재 기기에 가장 잘 일치하는 각 리소스의 버전을 선택합니다.

주의: 대체 리소스를 정의할 때는 기본 구성에서 리소스도 정의해야 합니다. 그러지 않으면 기기에서 구성을 변경할 때 앱에 런타임 예외가 발생할 수 있습니다. 예를 들어 values-en에만 문자열을 추가하고 values에는 추가하지 않으면 사용자가 기본 시스템 언어를 변경할 때 앱에서 Resource Not Found 예외가 발생할 수도 있습니다.

표 2에는 유효한 구성 한정자가 우선순위 순으로 나열되어 있습니다. 각 한정자를 대시로 구분하여 하나의 디렉터리 이름에 여러 한정자를 추가할 수 있습니다. 리소스 디렉터리에 여러 한정자를 사용하는 경우 표에 나열된 순서대로 디렉터리 이름에 추가해야 합니다.

표 2. 구성 한정자 이름

구성 한정자 값 설명
MCC 및 MNC 예:
mcc310
mcc310-mnc004
mcc208-mnc00

모바일 국가 코드(MCC). 필요한 경우 기기의 SIM 카드에 있는 모바일 네트워크 코드(MNC)를 뒤이어 표기합니다. 예를 들어 mcc310은 모든 이동통신사를 포함한 미국이고, mcc310-mnc004는 Verizon을 사용하는 미국, mcc208-mnc00은 Orange를 사용하는 프랑스입니다.

기기가 무선 연결(GSM 휴대전화)을 사용하는 경우 MCC 및 MNC 값은 SIM 카드에서 가져옵니다.

예를 들어 MCC만 단독으로 사용하여 앱에 국가별 합법적 리소스를 포함할 수 있습니다. 언어만을 기준으로 하여 지정해야 한다면 대신 언어, 스크립트(선택사항), 지역(선택사항) 한정자를 사용합니다. MCC와 MNC 한정자를 사용하는 경우 주의해서 사용하고 제대로 작동하는지 테스트합니다.

또한, 구성 필드 mccmnc를 참고하세요. 이 구성 필드는 각각 모바일 국가 코드와 모바일 네트워크 코드를 나타냅니다.

언어, 스크립트(선택사항), 지역(선택사항) 예:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419
b+zh+Hant
b+sr+Latn+RS

언어는 두 글자의 ISO 639-1 언어 코드로 정의되고, 뒤이어 두 글자의 ISO 3166-1-alpha-2 지역 코드(앞에 소문자 r이 추가됨)가 선택적으로 따라옵니다.

코드는 대소문자를 구분하지 않습니다. r 접두사는 지역 부분을 구별하는 데 사용됩니다. 지역만 지정할 수는 없습니다.

Android 7.0(API 수준 24)에서는 BCP 47 언어 태그 지원이 추가되었습니다. 이 태그를 사용하여 언어 및 지역별 리소스를 정규화할 수 있습니다. 언어 태그 하나는 하나 이상의 하위 태그 시퀀스로 구성됩니다. 각각의 하위 태그는 전체 태그로 식별되는 언어의 범위를 구체화하거나 좁히는 역할을 합니다. 언어 태그에 관한 자세한 내용은 언어 식별을 위한 태그를 참고하세요.

BCP 47 언어 태그를 사용하려면 b+와 두 글자의 ISO 639-1 언어 코드를 연결합니다. +로 구분된 추가적인 하위 태그를 뒤에 옵션으로 덧붙일 수도 있습니다.

사용자가 시스템 설정에서 언어를 변경하면 앱의 수명 주기가 남아 있는 동안 언어 태그가 변경될 수 있습니다. 런타임 시 앱에 미치는 영향에 관한 자세한 내용은 구성 변경 처리를 참고하세요.

앱을 다른 언어로 현지화하기 위한 전체 가이드는 앱 현지화를 참고하세요.

또한 정의된 언어 목록을 제공하는 getLocales() 메서드를 참고하세요. 이 목록에는 기본 언어가 포함됩니다.

레이아웃 방향 ldrtl
ldltr

앱의 레이아웃 방향입니다. ldrtl은 '오른쪽에서 왼쪽'을 의미합니다. ldltr은 '왼쪽에서 오른쪽'을 의미하며 기본적으로 내포된 값입니다.

레이아웃이나 드로어블, 값 등 모든 리소스에 적용할 수 있습니다.

예를 들어 아랍어용 특정 레이아웃을 제공하고 페르시아어나 히브리어 등 다른 '오른쪽에서 왼쪽으로 쓰는' 언어용 일반 레이아웃을 제공하려는 경우 다음과 같은 디렉터리를 사용합니다.

res/
  layout/
    main.xml (기본 레이아웃)
  layout-ar/
    main.xml (아랍어용 특정 레이아웃)
  layout-ldrtl/
    main.xml('ar' 언어 한정자의 우선순위가 더 높으므로 아랍어를 제외한 모든 오른쪽에서 왼쪽으로 쓰는 언어)

참고: 앱에서 오른쪽에서 왼쪽 레이아웃 기능을 활성화하려면 SupportsRtl"true"로 설정하고 TargetSdkVersion을 17 이상으로 설정해야 합니다.

API 수준 17에 추가되었습니다.

최소 너비 sw<N>dp

예:
sw320dp
sw600dp
sw720dp

앱에서 사용할 수 있는 가장 짧은 화면 영역 크기입니다. 특히 앱 창의 smallestWidth는 사용할 수 있는 가장 짧은 창의 높이와 너비입니다. 창에 '가능한 최소 너비'로 생각해도 됩니다. 이 한정자를 사용하여 앱의 UI에 사용할 수 있는 너비가 <N>dp 이상이 되도록 할 수 있습니다.

예를 들어 언제나 최소 600dp에서 최소 크기의 화면 공간이 레이아웃에 필요한 경우, 이 한정자를 사용하여 res/layout-sw600dp/ 디렉터리에서 레이아웃 리소스를 만들 수 있습니다. 시스템은 사용 가능한 화면의 최소 크기가 600dp인 경우에만 이런 리소스를 사용하고, 이때 사용자 쪽에서 600dp가 높이이든 너비이든 관계없습니다. 창의 크기가 조절되거나(사용 가능한 너비/높이 변경) 위치가 조정되면(시스템 인셋이 변경될 수 있음) 최소 너비가 변경될 수 있습니다.

레이아웃 디자인에서 흔히 너비가 구동 인자로 사용되므로 최소 너비를 사용하여 일반 화면 크기를 결정하는 방법이 유용합니다. UI는 세로로 스크롤되는 경우가 많지만 가로로 필요한 최소한의 공간에 관한 제약 조건이 상당히 심합니다.

사용 가능한 너비 또한 핸드셋용으로 단일 창 레이아웃을 사용할지 또는 태블릿용으로 다중 창 레이아웃을 사용할지를 결정하는 데 있어서 주요 요소입니다. 따라서 개발자는 각 기기에서 가능한 가장 작은 너비에 관해 가장 많이 고려하게 됩니다.

기기의 최소 너비는 화면 장식과 시스템 UI를 감안합니다. 예를 들어 화면상에서 최소 너비의 축 주변 공간을 차지하는 영구 UI 요소가 있다면 시스템은 최소 너비를 실제 화면 크기보다 작게 선언합니다. 이것은 개발자의 UI가 사용할 수 없는 화면 픽셀이기 때문입니다.

일반 화면 크기에서 여기에 사용할 수 있는 몇 가지 값은 다음과 같습니다.

  • 320 - 다음과 같은 화면 설정을 사용하는 기기
    • 240x320ldpi(QVGA 핸드셋)
    • 320x480mdpi(핸드셋)
    • 480x800hdpi(고밀도 핸드셋)
  • 480 - 480x800mdpi(태블릿/핸드셋) 등의 화면
  • 600 - 600x1024mdpi(7인치 태블릿) 등의 화면
  • 720 - 720x1280mdpi(10인치 태블릿) 등의 화면

앱이 smallestWidth 한정자의 여러 값이 포함된 여러 개의 리소스 디렉터리를 제공하면 시스템은 기기의 smallestWidth에 가장 가깝지만 이를 초과하지 않는 값을 사용합니다.

API 수준 13에 추가되었습니다.

그 외에도 앱과 호환되는 최소한의 smallestWidth를 선언하는 android:requiresSmallestWidthDp 속성과 기기의 smallestWidth 값을 유지하는 smallestScreenWidthDp 구성 필드도 참고하세요.

이 한정자를 사용하여 다양한 화면에 맞게 디자인하는 방법에 관한 자세한 내용은 다양한 화면 크기 지원을 참고하세요.

사용 가능한 너비 및 높이 w<N>dp
h<N>dp

예:
w720dp
w1024dp
h720dp
h1024dp

사용할 수 있는 최소 화면 너비 또는 높이(<N> 값으로 정의된 dp 단위)를 지정합니다. 이 너비나 높이로 리소스를 사용합니다. 이러한 구성 값은 기기 방향이 세로 모드와 가로 모드 간에 변경되거나, 기기가 접히거나 펼쳐지거나, 시스템이 멀티 윈도우 모드로 전환되거나 모드를 종료할 때 현재 디스플레이 너비 및 높이와 비교됩니다. 멀티 윈도우 모드에서 이 값은 기기 화면의 너비와 높이를 반영하는 것이 아니라 앱이 포함된 창의 너비와 높이를 반영합니다. 마찬가지로 삽입된 활동의 경우 값은 화면의 너비 및 높이가 아닌 개별 활동의 너비 및 높이와 관련이 있습니다. 자세한 내용은 활동 삽입을 참고하세요.

사용 가능한 너비와 높이는 다중 창 레이아웃을 사용할지 판단하는 데 유용한 경우가 많습니다. 태블릿 기기에서도 가로 모드에서와 동일한 세로 모드 방향의 다중 창 레이아웃을 필요로 하지 않는 경우가 많기 때문입니다. 따라서 화면 크기 및 방향 한정자를 모두 함께 사용하는 대신 레이아웃에 필요한 최소 너비나 높이를 지정하는 데 사용할 수 있습니다.

앱이 여러 리소스 디렉터리에 다양한 이러한 구성 값을 제공하면 시스템은 기기의 현재 화면 너비에 가장 가깝지만 이를 초과하지 않는 값을 사용합니다. 가장 가까운 값은 실제 화면 너비와 지정된 너비 간의 차이에 실제 화면 높이와 지정된 높이 간의 차이를 더하여 결정됩니다. 이때 지정되지 않은 높이와 너비의 값은 0입니다.

창 인셋에서 차지한 영역은 이 값에서 제외됩니다. 따라서 기기의 디스플레이 가장자리에 영구 UI 요소가 있으면 너비 및 높이 값은 실제 화면 크기보다 작습니다. Window.setDecorFitsSystemWindows 또는 WindowCompat.setDecorFitsSystemWindows를 사용하여 앱이 가장자리에서 가장자리까지 표시될 때도 마찬가지입니다.

고정되지 않은 일부 세로 화면 장식(예: 전체 화면일 때 숨겨질 수 있는 휴대전화 상태 표시줄)은 여기서 고려되지 않습니다. 제목 표시줄이나 작업 모음과 같은 창 장식도 마찬가지이므로 앱은 지정하는 것보다 약간 작은 공간을 처리할 준비가 되어 있어야 합니다.

참고: 시스템은 너비와 높이에서 모두 일치하는 리소스를 선택합니다. 따라서 둘 다 지정하는 리소스가 하나만 지정하는 리소스보다 더 선호됩니다. 예를 들어 실제 화면의 너비가 720dp, 높이가 1280dp이고 한 리소스는 w720dp로 검증되고 다른 리소스는 w700dp-h1200dp로 검증된 경우, 전자가 지정된 것과 정확히 일치하더라도 후자가 선택됩니다.

API 수준 13에 추가되었습니다.

현재 화면 너비와 높이를 보유하는 screenWidthDpscreenHeightDp 구성 필드도 참고하세요.

이 한정자를 사용하여 다양한 화면에 맞게 디자인하는 방법에 관한 자세한 내용은 다양한 화면 크기 지원을 참고하세요.

화면 크기 small
normal
large
xlarge
  • small: 저밀도 QVGA 화면과 비슷한 크기의 화면입니다. 작은 화면의 최소 레이아웃 크기는 약 320x426dp 단위입니다. 이 화면의 예로는 QVGA 저밀도 및 VGA 고밀도가 있습니다.
  • normal: 중밀도 HVGA 화면과 비슷한 크기의 화면입니다. 일반 화면의 최소 레이아웃 크기는 약 320x470dp 단위입니다. 이러한 화면의 예로는 WQVGA 저밀도, HVGA 중밀도, WVGA 고밀도가 있습니다.
  • large: 중밀도 VGA 화면과 비슷한 크기의 화면입니다. 대형 화면의 최소 레이아웃 크기는 약 480x640dp 단위입니다. 예로는 VGA 및 WVGA 중밀도 화면이 있습니다.
  • xlarge: 일반적인 중밀도 HVGA 화면보다 상당히 큰 화면을 말합니다. 특대형 화면의 최소 레이아웃 크기는 약 720x960dp 단위입니다. 대부분의 경우 특대형 화면이 장착된 기기는 주머니에 휴대하기에 너무 크고 태블릿 스타일 기기일 가능성이 높습니다. API 수준 9에 추가되었습니다.

참고: 크기 한정자를 사용해도 리소스가 해당 크기 화면 전용임을 암시하지 않습니다. 대체 리소스에 현재 기기 구성과 더욱 잘 맞는 한정자를 제공하지 않으면 시스템에서 임의의 최적 일치 리소스를 사용할 수 있습니다.

주의: 모든 리소스가 현재 화면보다 크기 한정자를 사용하는 경우 시스템은 이를 사용하지 않으며 런타임 시 앱이 다운됩니다 예를 들어 모든 레이아웃 리소스에 xlarge 한정자가 태그로 지정되어 있지만 기기의 화면이 일반 크기인 경우가 이에 해당합니다.

API 수준 4에 추가되었습니다.

screenLayout 구성 필드도 참고하세요. 이 필드는 화면이 소형인지, 일반 크기인지, 대형인지를 나타냅니다.

자세한 내용은 화면 호환성 개요를 참고하세요.

화면 가로세로 비율 long
notlong
  • long: WQVGA, WVGA, FWVGA 등의 긴 화면
  • notlong: QVGA, HVGA, VGA 등의 길지 않은 화면

API 수준 4에 추가되었습니다.

순전히 화면의 가로세로 비율에 기반합니다(long 화면이 더 넓습니다). 화면 방향과는 관계가 없습니다.

화면이 긴 화면인지를 나타내는 screenLayout 구성 필드도 참고하세요.

원형 화면 round
notround
  • round: 원형 화면(예: 원형 웨어러블 기기)
  • notround: 직사각형 화면(예: 스마트폰 또는 태블릿)

API 수준 23에 추가되었습니다.

화면이 원형인지 여부를 나타내는 isScreenRound() 구성 메서드도 참고하세요.

넓은 색 공간 widecg
nowidecg
  • widecg: Display P3, AdobeRGB 등과 같은 넓은 색 공간으로 표시합니다.
  • nowidecg: sRGB와 같은 좁은 색 공간으로 표시합니다.

API 수준 26에 추가되었습니다.

화면이 넓은 색 공간을 가졌는지 나타내는 isScreenWideColorGamut() 구성 메서드도 참고하세요.

HDR(High Dynamic Range) highdr
lowdr
  • highdr: 높은 동적 범위로 표시합니다.
  • lowdr: 낮은/표준 동적 범위로 표시합니다.

API 수준 26에 추가되었습니다.

화면에 HDR 기능이 있는지 나타내는 isScreenHdr() 구성 메서드도 참고하세요.

화면 방향 port
land
  • port: 기기가 세로 모드 방향(수직)입니다.
  • land: 기기가 가로 모드 방향(수평)입니다.

사용자가 화면을 돌리는 경우 앱 수명 중에 화면 방향이 변경될 수 있습니다. 런타임 시 앱에 미치는 영향에 관한 자세한 내용은 구성 변경 처리를 참고하세요.

현재 기기 방향을 나타내는 orientation 구성 필드도 참고하세요.

UI 모드 car
desk
television
appliance
watch
vrheadset
  • car: 기기가 차량용 도크에서 표시되고 있습니다.
  • desk: 기기가 데스크용 도크에서 표시되고 있습니다.
  • television: 기기가 텔레비전에 표시되고, 사용자가 멀리 떨어져 있는 큰 화면에 UI가 표시되는 '3m' 환경을 제공하며, 이 환경은 기본적으로 D패드 또는 기타 비 포인터 상호작용을 지향합니다
  • appliance: 기기가 가전 제품 역할을 하고 있으며, 디스플레이 화면이 없습니다.
  • watch: 기기에 화면이 있고 손목에 착용합니다.
  • vrheadset: 기기가 가상 현실 헤드셋에서 표시됩니다.

API 수준 8에 추가되었습니다. television은 API 13에, watch는 API 20에 추가되었습니다.

기기가 도크에 삽입되거나 도크에서 제거될 때 앱이 반응할 수 있는 방법에 관한 자세한 내용은 도킹 상태와 유형 확인 및 모니터링을 참고하세요.

UI 모드는 사용자가 기기를 도크에 놓는 경우 앱 수명 중에 변경될 수 있습니다. 이러한 모드 중 일부는 UiModeManager로 사용 설정 또는 사용 중지할 수 있습니다. 런타임 시 앱에 미치는 영향에 관한 자세한 내용은 구성 변경 처리를 참고하세요.

야간 모드 night
notnight
  • night: 야간
  • notnight: 주간

API 수준 8에 추가되었습니다.

야간 모드가 자동 모드인 상태(기본)로 설정되어 있으면 앱의 수명 중에 모드가 변경될 수 있습니다. 이 경우 하루 중 시간대를 기반으로 변경됩니다. 이 모드는 UiModeManager로 사용 설정 또는 사용 중지할 수 있습니다. 런타임 시 앱에 미치는 영향에 관한 자세한 내용은 구성 변경 처리를 참고하세요.

화면 픽셀 밀도(dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi: 저밀도 화면, 약 120dpi
  • mdpi: 중밀도(일반적인 HVGA에서) 화면, 약 160dpi
  • hdpi: 고밀도 화면, 약 240dpi
  • xhdpi: 초고밀도 화면, 약 320dpi API 수준 8에 추가되었습니다.
  • xxhdpi: 초초고밀도 화면, 약 480dpi API 수준 16에 추가되었습니다.
  • xxxhdpi: 초초초고밀도 사용(런처 아이콘만 해당, 다양한 픽셀 밀도 지원 참고), 약 640dpi API 수준 18에 추가되었습니다.
  • nodpi: 기기 밀도에 맞게 크기를 조정하지 않을 비트맵 리소스에 사용됩니다.
  • tvdpi: mdpi와 hdpi 사이에 있는 화면, 약 213dpi. '기본' 밀도 그룹으로 간주되지 않습니다. 대부분 720p 7텔레비전용이며 대부분의 앱에는 필요하지 않습니다. 1080p TV 패널에는 xhdpi를, 4K TV 패널에는 xxxhdpi를 사용하세요. API 레벨 13에 추가되었습니다.
  • anydpi: 모든 화면 밀도와 일치하고 다른 한정자보다 우선합니다. 벡터 드로어블에 유용합니다. API 수준 21에 추가되었습니다.
  • nnndpi: 표준이 아닌 밀도를 표현하는 데 사용합니다. nnn은 양의 정수 화면 밀도입니다. 대부분의 경우 사용되지 않습니다. 표준 밀도 버킷을 사용하면 시장의 다양한 기기 화면 밀도를 지원하는 오버헤드가 크게 줄어듭니다.

6개의 기본 밀도(tvdpi 밀도 무시) 간 확장 비율은 3:4:6:8:12:16입니다. 따라서 ldpi 9x9 비트맵은 mdpi 12x12이며, hdpi 18x18은 xhdpi 24x24입니다.

참고: 밀도 한정자를 사용한다고 해서 리소스가 해당 밀도 화면 전용임을 의미하지는 않습니다. 대체 리소스에 현재 기기 구성과 더욱 잘 맞는 한정자를 제공하지 않으면 시스템에서 임의의 최적 일치 리소스를 사용합니다.

다양한 화면 밀도를 처리하는 방법과 Android에서 현재 밀도에 맞도록 비트맵을 조정하는 방법에 관한 자세한 내용은 화면 호환성 개요를 참고하세요.

터치스크린 유형 notouch
finger
  • notouch: 기기에 터치스크린이 없습니다.
  • finger: 기기에 터치스크린이 있으며 이를 사용자의 손가락을 사용한 방향 지시 상호작용을 통해 쓰도록 되어 있습니다.

기기에서 사용되는 터치스크린의 유형을 나타내는 touchscreen 구성 필드도 참고하세요.

키보드 사용 가능 여부 keysexposed
keyshidden
keyssoft
  • keysexposed: 기기에서 키보드를 사용할 수 있습니다. 기기에 소프트웨어 키보드가 사용 설정되어 있으면(가능성 높음) 하드웨어 키보드가 사용자에게 노출되지 않거나 기기에 하드웨어 키보드가 없는 경우에도 사용됩니다. 소프트웨어 키보드가 제공되지 않거나 사용 중지된 경우 하드웨어 키보드가 노출되었을 때에만 사용됩니다.
  • keyshidden: 기기에서 하드웨어 키보드를 사용할 수 있지만 숨겨져 있고 이에 더하여 기기에 소프트웨어 키보드가 사용 설정되어 있지 않습니다.
  • keyssoft: 소프트웨어 키보드가 표시되어 있는지 여부와 상관없이 기기에 소프트웨어 키보드가 사용 설정되어 있습니다.

keysexposed 리소스를 제공하지만 keyssoft 리소스는 제공하지 않는다면, 시스템은 소프트웨어 키보드가 사용 설정되어 있는 동안은 키보드가 보이는지 여부와 관계없이 keysexposed 리소스를 사용합니다.

이는 사용자가 하드웨어 키보드를 여는 경우 앱 수명 중에 변경될 수 있습니다. 런타임 시 앱에 미치는 영향에 관한 자세한 내용은 구성 변경 처리를 참고하세요.

또한, 구성 필드 hardKeyboardHiddenkeyboardHidden도 참고하세요. 이 필드는 각각 하드웨어 키보드의 가시성과 모든 종류의 키보드(소프트웨어 포함)의 가시성을 나타냅니다.

기본 텍스트 입력 방법 nokeys
qwerty
12key
  • nokeys: 기기에 텍스트 입력을 위한 하드웨어 키가 없습니다.
  • qwerty: 기기에 하드웨어 QWERTY 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는 무관).
  • 12key: 기기에 하드웨어 12키 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는 무관).

사용 가능한 기본 텍스트 입력 방법을 나타내는 keyboard 구성 필드도 참고하세요.

플랫폼 버전(API 수준) 예:
v3
v4
v7

기기에서 지원하는 API 수준입니다. 예를 들어, v1은 API 수준 1용이고(Android 1.0 이상 기기), v4는 API 수준 4용(Android 1.6 이상 기기)입니다. 이러한 값에 관한 자세한 내용은 Android API 수준 문서를 참고하세요.

참고: Android 버전별로 지원되지 않는 한정자가 있을 수 있습니다. 새 한정자를 암시적으로 사용하면 이전 기기에서 무시할 수 있도록 플랫폼 버전 한정자가 추가됩니다. 예를 들어 w600dp 한정자를 사용하면 자동으로 v13 한정자를 포함합니다. 사용 가능한 너비 한정자가 API 수준 13부터 새로 도입되었기 때문입니다. 문제를 방지하려면 항상 기본 리소스 집합(한정자가 없는 리소스 집합)을 포함합니다. 자세한 내용은 리소스로 최상의 기기 호환성 제공 섹션을 참고하세요.

한정자 이름 규칙

구성 한정자 이름 사용에 관한 몇 가지 규칙은 다음과 같습니다.

  • 한 가지 리소스 세트에 여러 개의 한정자를 사용할 수 있으며, 대시로 구분하면 됩니다. 예를 들어 drawable-en-rUS-land는 가로 방향의 US-English 기기에 적용합니다.
  • 한정자 순서는 표 2에 표시된 순이어야 합니다.
    • 잘못됨: drawable-hdpi-port/
    • 올바름: drawable-port-hdpi/
  • 대체 리소스 디렉터리는 중첩될 수 없습니다. 예를 들어 res/drawable/drawable-en/은 있을 수 없습니다.
  • 값은 대소문자를 구분하지 않습니다. 리소스 컴파일러는 처리하기 전에 디렉터리 이름을 소문자로 변환하여 대소문자를 구분하지 않는 파일 시스템에서 문제를 방지합니다. 이름에서 대문자는 가독성을 향상하는 목적으로만 사용됩니다.
  • 각 한정자 유형에 한 개의 값만 지원됩니다. 예를 들어 스페인과 프랑스에 같은 드로어블 파일을 사용하고자 하는 경우, 이름이 drawable-es-fr/인 디렉터리는 사용할 수 없습니다. 대신 drawable-es/drawable-fr/같이 적절한 파일이 포함된 두 개의 리소스 디렉터리가 필요합니다. 다만 양쪽 위치에 같은 파일을 실제로 복제할 필요는 없습니다. 대신 별칭 리소스 만들기 섹션에 설명된 대로 리소스의 별칭을 만들 수 있습니다.

이런 한정자로 이름을 지정한 디렉터리에 대체 리소스를 저장하고 나면 Android가 현재 기기 구성에 기초하여 앱에 자동으로 리소스를 적용합니다. 리소스가 요청될 때마다 Android는 요청된 리소스 파일이 포함된 대체 리소스 디렉터리를 확인한 다음 최적 일치 리소스를 찾습니다.

특정 기기 구성에 일치하는 대체 리소스가 없는 경우, Android는 상응하는 기본 리소스(구성 한정자를 포함하지 않는 특정 리소스 유형에 대한 리소스 세트)를 사용합니다.

별칭 리소스 만들기

둘 이상의 기기 구성에 사용하지만 기본 리소스로 제공하지 않으려는 리소스가 있는 경우 둘 이상의 대체 리소스 디렉터리에 동일한 리소스를 넣을 필요가 없습니다. 대신 기본 리소스 디렉터리에 저장된 리소스의 별칭 역할을 하는 대체 리소스를 만들 수 있습니다.

참고: 일부 리소스만 다른 리소스에 대한 별칭을 만들 수 있는 메커니즘을 제공합니다. 특히, xml/ 디렉터리의 애니메이션, 메뉴, 원시 및 기타 지정되지 않은 리소스는 이 기능을 제공하지 않습니다.

예를 들어 icon.png라는 앱 아이콘이 있고 다른 언어용 고유 버전이 필요한데, 캐나다 영어와 캐나다 프랑스어, 두 언어에서 동일한 버전을 사용해야 한다고 가정해 보겠습니다. 이 경우 캐나다 영어와 캐나다 프랑스어 모두에 대한 리소스 디렉터리로 동일한 이미지를 복사할 필요가 없습니다. 대신 icon.png 이외의 이름(예: icon_ca.png)을 사용하여 두 언어 모두에 사용되는 이미지를 저장하고 기본 res/drawable/ 디렉터리에 넣으면 됩니다. 그런 다음 <bitmap> 요소를 사용하여 icon_ca.png 리소스를 참조하는 res/drawable-en-rCA/res/drawable-fr-rCA/에서 icon.xml 파일을 생성합니다. 이렇게 하여 한 버전의 PNG 파일과 이 파일을 가리키는 작은 XML 파일 2개를 저장할 수 있습니다. 자세한 내용은 다음 섹션의 예를 참고하세요.

드로어블

기존 드로어블에 별칭을 생성하려면 <drawable> 요소를 사용합니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="icon">@drawable/icon_ca</drawable>
</resources>

파일을 res/values-en-rCA/와 같은 대체 리소스 디렉터리에 icon.xml로 저장하면, R.drawable.icon로 참조할 수 있는 리소스로 컴파일됩니다. 그러나 이것은 실제로는 R.drawable.icon_ca 리소스(res/drawable/에 저장됨)의 별칭입니다.

레이아웃

기존 레이아웃에 별칭을 생성하려면 <merge>로 래핑된 <include> 요소를 사용합니다.

<?xml version="1.0" encoding="utf-8"?>
<merge>
    <include layout="@layout/main_ltr"/>
</merge>

파일을 main.xml로 저장하면, R.layout.main으로 참조할 수 있는 리소스로 컴파일됩니다. 그러나 이것은 실제로는 R.layout.main_ltr 리소스의 별칭입니다.

문자열 및 기타 간단한 값

기존 문자열에 대한 별칭을 만들려면 원하는 문자열의 리소스 ID를 새 문자열의 값으로 사용하면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello</string>
    <string name="hi">@string/hello</string>
</resources>

이제 R.string.hi 리소스는 R.string.hello의 별칭입니다.

색상과 같은 다른 간단한 값도 동일하게 작동합니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="red">#f00</color>
    <color name="highlight">@color/red</color>
</resources>

앱 리소스에 액세스

일단 어떤 리소스를 애플리케이션에 제공한 다음에는, 해당 리소스의 리소스 ID를 참조함으로써 이를 적용할 수 있습니다. 모든 리소스 ID는 aapt 도구가 자동으로 생성하는 프로젝트의 R 클래스에서 정의됩니다.

애플리케이션이 컴파일되면 aaptR 클래스를 생성하며, 이 클래스 안에 res/ 디렉터리에 있는 모든 리소스의 리소스 ID가 들어 있습니다. 각 리소스 유형에는 모든 드로어블 리소스의 R.drawable 같은 R 서브클래스가 있습니다. 그리고 해당 유형의 각 리소스에는 정적 정수가 있습니다(예: R.drawable.icon). 이 정수가 리소스를 검색하는 데 사용할 수 있는 리소스 ID입니다.

리소스 ID가 R 클래스에서 지정되기는 하지만, 리소스 ID를 찾기 위해 이 클래스를 볼 필요는 없습니다. 리소스 ID는 항상 다음과 같이 구성됩니다.

  • 리소스 유형: 각 리소스는 string, drawable, layout와 같은 '유형'으로 그룹화됩니다. 다양한 유형에 관한 자세한 내용은 리소스 유형 개요를 참고하세요.
  • 리소스 이름: 리소스가 단순 값(예: 문자열 등)일 경우, 확장자를 제외한 파일 이름이나 XML android:name 속성 값 중 하나입니다.

리소스에 액세스하는 방법은 두 가지가 있습니다.

  • 코드: R 클래스의 서브클래스에서 다음과 같이 정적 정수를 사용합니다.
    R.string.hello

    string은 리소스 유형이고 hello는 리소스 이름입니다. 리소스 ID를 이 형식으로 제공하면 리소스에 액세스할 수 있는 Android API가 많습니다. 자세한 내용은 코드에서 리소스 액세스 섹션을 참고하세요.

  • XML: R 클래스에서 정의된 리소스 ID에 상응하는 특수 XML 문법을 사용합니다. 예를 들면 다음과 같습니다.
    @string/hello

    string은 리소스 유형이고 hello는 리소스 이름입니다. 이 문법은 리소스로 값을 제공할 것으로 예상되는 어느 곳에나 XML 리소스 형태로 사용할 수 있습니다. 자세한 내용은 XML에서 리소스 액세스 섹션을 참고하세요.

코드에서 리소스 액세스

리소스 ID를 메서드 매개변수로 전달하면 코드 내 리소스를 사용할 수 있습니다. 예를 들어, ImageView를 설정하여 setImageResource()를 사용하는 res/drawable/myimage.png 리소스를 사용할 수 있습니다.

Kotlin

val imageView = findViewById(R.id.myimageview) as ImageView
imageView.setImageResource(R.drawable.myimage)

Java

ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);

Resources에서 메서드를 사용하는 개별 리소스를 검색할 수도 있으며, 이는 getResources()로 인스턴스를 가져올 수 있습니다.

문법

다음은 코드로 리소스를 참조하는 데 쓰는 문법입니다.

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name>은 리소스가 위치한 패키지의 이름입니다(자체 패키지의 리소스를 참조할 경우에는 필요하지 않음).
  • <resource_type>은 해당 리소스 유형의 R 서브클래스입니다.
  • <resource_name>은 확장자가 없는 리소스 파일 이름이거나 XML 요소의 android:name 속성 값입니다(단순 값의 경우).

각 리소스 유형 및 리소스 참조 방법에 관한 자세한 내용은 리소스 유형 개요를 참고하세요.

사용 사례

리소스 ID 매개변수를 허용하는 메서드가 많이 있고, Resources에서 메서드를 사용하여 리소스를 검색할 수 있습니다. Context.getResources()Resources의 인스턴스를 가져올 수 있습니다.

다음은 코드에서 리소스에 액세스한 몇 가지 예입니다.

Kotlin

// Load a background for the current screen from a drawable resource.
window.setBackgroundDrawableResource(R.drawable.my_background_image)

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID.
window.setTitle(resources.getText(R.string.main_title))

// Load a custom layout for the current screen.
setContentView(R.layout.main_screen)

// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in))

// Set the text on a TextView object using a resource ID.
val msgTextView = findViewById(R.id.msg) as TextView
msgTextView.setText(R.string.hello_message)

Java

// Load a background for the current screen from a drawable resource.
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID.
getWindow().setTitle(getResources().getText(R.string.main_title));

// Load a custom layout for the current screen.
setContentView(R.layout.main_screen);

// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in));

// Set the text on a TextView object using a resource ID.
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);

주의: R.java 파일을 직접 수정하지 마세요. 프로젝트가 컴파일될 때 aapt 도구에서 생성됩니다. 모든 변경사항은 다음번 컴파일에서 재정의됩니다.

XML에서 리소스 액세스

기존 리소스 참조를 사용하여 일부 XML 속성과 요소의 값을 정의할 수 있습니다. 이 작업은 레이아웃 파일을 생성할 때 위젯에 문자열과 이미지를 제공하기 위해 자주 하게 됩니다.

예를 들어 Button을 레이아웃에 추가하는 경우 버튼 텍스트에 문자열 리소스를 사용합니다.

<Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/submit" />

문법

다음은 XML 리소스로 리소스를 참조하는 데 쓰는 문법입니다.

@[<package_name>:]<resource_type>/<resource_name>
  • <package_name>은 리소스가 위치한 패키지의 이름입니다(같은 패키지의 리소스를 참조할 경우에는 필요하지 않음).
  • <resource_type>은 해당 리소스 유형의 R 서브클래스입니다.
  • <resource_name>은 확장자가 없는 리소스 파일 이름이거나 XML 요소의 android:name 속성 값입니다(단순 값의 경우).

각 리소스 유형 및 리소스 참조 방법에 관한 자세한 내용은 리소스 유형 개요를 참고하세요.

사용 사례

일부 경우에는 값에 대한 리소스를 반드시 XML로 사용해야 하지만(예: 위젯에 드로어블 이미지를 적용하는 경우), 단순 값을 허용하는 곳이라면 어디서든 XML로 리소스를 사용할 수도 있습니다. 예를 들어, 색상 리소스문자열 리소스를 포함한 다음과 같은 리소스 파일을 가지고 있다고 가정해 보겠습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="opaque_red">#f00</color>
   <string name="hello">Hello!</string>
</resources>

이와 같은 리소스는 다음의 레이아웃 파일에서 텍스트 색상과 텍스트 문자열을 설정하는 데 사용할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@color/opaque_red"
    android:text="@string/hello" />

이 경우, 리소스를 자체 패키지에서 가져왔으므로 리소스 참조에 패키지 이름을 지정하지 않아도 됩니다. 시스템 리소스를 참조하려면 다음 예와 같이 패키지 이름을 포함해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@android:color/secondary_text_dark"
    android:text="@string/hello" />

참고: 항상 문자열 리소스를 사용해야 애플리케이션이 다른 언어에 맞게 현지화될 수 있습니다. 대체 리소스(예: 현지화된 문자열) 생성에 관한 자세한 내용은 대체 리소스 제공을 참고하세요. 애플리케이션을 다른 언어로 현지화하는 방법에 관한 전체 가이드는 앱 현지화를 참고하세요.

XML의 리소스를 사용하여 별칭을 생성할 수도 있습니다. 예를 들어, 드로어블 리소스이면서 다른 드로어블 리소스의 별칭인 것을 생성할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/other_drawable" />

일견 중복되는 것처럼 들리지만, 대체 리소스를 사용할 때 매우 유용하게 쓰일 수 있습니다. 자세한 내용은 별칭 리소스 만들기 섹션을 참고하세요.

참조 스타일 속성

스타일 속성 리소스를 사용하면 현재 적용된 테마의 속성 값을 참조할 수 있습니다. 스타일 속성을 참조하면 하드코딩 값을 제공하는 대신 현재 테마에서 제공한 표준 변형과 일치하도록 스타일을 지정하여 UI 요소의 모양을 맞춤설정할 수 있습니다. 스타일 속성을 참조하는 것은 기본적으로 '이 속성이 정의한 스타일을 현재 테마로 사용하라'는 말과 같습니다.

스타일 속성을 참조하는 경우, 이름 문법은 일반적인 리소스 형식과 거의 똑같습니다. 다만 앳 기호(@)를 사용하는 대신 물음표(?)를 사용합니다. 리소스 유형 부분은 선택사항입니다. 참조 문법은 다음과 같습니다.

?[<package_name>:][<resource_type>/]<resource_name>

예를 들어 다음과 같이 속성을 참조하여 시스템 테마의 '보조' 텍스트 색상과 일치하도록 텍스트 색상을 설정할 수 있습니다.

<EditText id="text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="?android:textColorSecondary"
    android:text="@string/hello_world" />

여기서 android:textColor 속성이 현재 테마에 스타일 속성의 이름을 지정합니다. Android는 이제 android:textColorSecondary 스타일 속성에 적용된 값을 이 위젯의 android:textColor 값으로 사용합니다. 시스템 리소스 도구는 이 컨텍스트에서 속성 리소스가 예상된다는 것을 알기 때문에 유형(?android:attr/textColorSecondary)을 명시적으로 언급할 필요가 없습니다. attr 유형은 제외할 수 있습니다.

원본 파일 액세스

흔한 일은 아니지만, 원본 파일과 디렉터리에 액세스해야 하는 경우가 있습니다. 이 경우에는 res/에 파일을 저장하더라도 소용이 없습니다. res/에서 리소스를 읽는 방법은 리소스 ID를 사용하는 것뿐이기 때문입니다. 대신 assets/ 디렉터리에 리소스를 저장할 수 있습니다.

assets/ 디렉터리에 저장된 파일은 리소스 ID가 부여되지 않으므로, 이와 같은 리소스는 R 클래스나 XML 리소스에서 참조할 수 없습니다. 그 대신 일반 파일 시스템처럼 assets/ 디렉터리에 파일을 쿼리하고 AssetManager를 사용하여 원시 데이터를 읽을 수 있습니다.

하지만 원시 데이터(예: 동영상, 오디오 파일)를 읽는 기능만 필요한 경우라면, 파일을 res/raw/ 디렉터리에 저장한 다음 openRawResource()를 사용하여 일련의 바이트 스트림을 읽으면 됩니다.

플랫폼 리소스 액세스

Android에는 스타일, 테마, 레이아웃 등 여러 가지 표준 리소스가 포함되어 있습니다. 이와 같은 리소스에 액세스하려면 android 패키지 이름으로 리소스 참조를 한정합니다. 예를 들어 Android는 ListAdapter의 목록 항목으로 사용할 수 있는 레이아웃 리소스를 제공합니다.

Kotlin

listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, myarray)

Java

setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));

이 예에서 simple_list_item_1ListView의 항목에 대해 플랫폼이 정의한 레이아웃 리소스입니다. 목록 항목의 자체 레이아웃을 만드는 대신 이것을 사용해도 됩니다.

리소스와 연관된 최선의 기기 호환성 제공

앱이 여러 기기 구성을 지원하게 하려면, 언제나 앱이 사용하는 각 유형의 리소스에 기본 리소스를 제공하는 것이 매우 중요합니다.

예를 들어 앱이 여러 언어를 지원할 경우, 항상 언어 및 지역 한정자 없이 values/ 디렉터리(문자열이 저장된 디렉터리)를 포함시켜야 합니다. 그러지 않고 언어와 지역 한정자가 있는 디렉터리에 모든 문자열을 넣으면, 문자열이 지원하지 않는 언어로 설정된 기기에서 앱을 실행하면 다운됩니다.

기본 values/ 리소스를 제공하는 한 사용자가 제공되는 언어를 이해하지 못하더라도 앱이 올바르게 실행됩니다. 다운되는 것보다는 낫습니다.

마찬가지로 화면 방향을 기준으로 다른 레이아웃 리소스를 제공하는 경우 기본값으로 한 방향을 선택합니다. 예를 들어 가로 방향에는 layout-land/로, 세로 방향에는 layout-port/로 레이아웃 리소스를 제공하는 대신 하나를 기본으로 남겨 두세요. 가로 방향인 경우 layout/으로 제공하고, 세로 방향인 경우 layout-port/로 제공하는 식으로 하면 됩니다.

앱이 예상치 못한 구성에서 실행될 수 있을 뿐만 아니라 Android의 새 버전에서 이전 버전에서는 지원하지 않는 구성 한정자를 추가할 수도 있으므로, 기본 리소스를 제공하는 것이 중요합니다. 새 리소스 한정자를 사용하지만 이전 버전의 Android와 코드 호환성을 유지하는 경우 이전 버전의 Android에서 앱을 실행할 때 기본 리소스가 제공되지 않으면 앱이 다운됩니다. 새 한정자로 이름을 지정한 리소스를 사용할 수 없기 때문입니다.

예를 들어 minSdkVersion이 4로 설정되어 있는데 야간 모드(API 수준 8에서 추가된 night 또는 notnight)를 사용하여 모든 드로어블 리소스를 한정할 경우, API 수준 4 기기가 드로어블 리소스에 액세스하지 못하고 다운됩니다. 이 경우 notnight를 기본 리소스로 사용하는 것이 좋습니다. 따라서 해당 한정자를 제외하고 드로어블 리소스를 drawable/ 또는 drawable-night/에 넣습니다.

그러므로 최선의 기기 호환성을 제공하려면 언제나 앱에서 반드시 제대로 실행해야 하는 리소스에 기본 리소스를 제공하세요. 그런 다음 구성 한정자를 사용하여 특정 기기 구성에 관한 대체 리소스를 만듭니다.

이 규칙에는 한 가지 예외가 있습니다. 앱의 minSdkVersion이 4 이상인 경우 화면 밀도 한정자와 함께 대체 드로어블을 제공할 때 기본 드로어블 리소스가 필요하지 않습니다. 기본 드로어블 리소스가 없어도 Android가 대체 화면 밀도에서 최적 일치 밀도를 찾아 필요한 경우 비트맵을 확장합니다. 하지만 모든 기기 유형에서 최고의 환경을 제공하려면 3개의 밀도 유형 모두에 대체 드로어블을 제공하세요.

Android가 가장 잘 일치하는 리소스를 찾는 방법

대체를 제공한 리소스를 요청하면 Android에서 현재 기기 구성에 따라 런타임 시 사용할 대체 리소스를 선택합니다. Android에서 대체 리소스를 선택하는 방법을 보여주기 위해 다음과 같이 각각 동일한 이미지의 다른 버전이 포함된 드로어블 디렉터리가 있다고 가정해 보겠습니다.

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

또한 기기 구성이 다음과 같다고 가정하겠습니다.

언어 = en-GB
화면 방향 = port
화면 픽셀 밀도 = hdpi
터치스크린 유형 = notouch
기본 텍스트 입력 방법 = 12key

Android는 기기 구성을 이용 가능한 대체 리소스와 비교하여, drawable-en-port에서 드로어블을 선택합니다.

시스템은 다음 로직으로 사용할 리소스를 결정합니다.

그림 2. Android에서 최적 일치 리소스를 찾는 방법에 관한 플로우 차트

  1. 기기 구성과 충돌하는 리소스 파일을 제거합니다.

    drawable-fr-rCA/ 디렉터리는 en-GB 언어와 충돌하므로 제거되었습니다.

    drawable/
    drawable-en/
    drawable-fr-rCA/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    예외: 화면 픽셀 밀도는 충돌로 인해 제거되지 않는 하나의 한정자입니다. 기기의 화면 밀도가 hdpi라도, 현 시점에서는 모든 화면 밀도가 일치로 간주되므로 drawable-port-ldpi/를 제거하지 않습니다. 자세한 내용은 화면 호환성 개요를 참고하세요.

  2. 목록(표 2)에서 다음으로 우선순위가 높은 한정자를 선택합니다. MCC부터 시작하세요.
  3. 리소스 디렉터리 중에 이 한정자를 포함한 것이 있나요?
    • 없을 경우, 2단계로 돌아가 다음 한정자를 살펴봅니다. 이 예에서는 언어 한정자에 도달할 때까지 대답이 '아니요'입니다.
    • '예'인 경우 4단계로 진행합니다.
  4. 이 한정자를 포함하지 않는 리소스 디렉터리는 제외합니다. 이 예에서는 시스템이 언어 한정자를 포함하지 않는 모든 디렉터리를 제거합니다.
    drawable/
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    예외: 해당 한정자가 화면 픽셀 밀도인 경우, Android에서는 기기 화면 밀도와 가장 근접하게 일치하는 옵션을 선택합니다. 일반적으로 Android는 작은 원래 이미지를 확장하는 것보다 큰 원래 이미지를 축소하는 것을 선호합니다. 자세한 내용은 화면 호환성 개요를 참고하세요.

  5. 디렉터리가 하나만 남을 때까지 2, 3, 4단계를 반복합니다. 이 예에서는 화면 한정자가 일치하는 항목이 있는 다음 한정자입니다. 따라서 화면 방향을 지정하지 않는 리소스는 제거됩니다.
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    

    남은 디렉터리는 drawable-en-port입니다.

이 절차는 요청된 각 리소스에 대해 실행되지만 시스템은 일부 측면을 최적화합니다. 이러한 최적화 중 하나로, 기기 구성이 알려진 뒤에 일치하지 않는 대체 리소스가 제거될 수 있습니다. 예를 들면 설정 언어가 영어인 경우 영어가 아닌 언어로 설정된 언어 한정자가 포함된 모든 리소스 디렉터리는 확인된 리소스 풀에 포함되지 않습니다(하지만 언어 한정자가 없는 리소스 디렉터리는 계속 포함됨).

화면 크기 한정자를 기반으로 리소스를 선택할 때 시스템은 가장 잘 일치하는 리소스가 없다면 현재 화면보다 작은 화면에 지정된 리소스를 사용합니다. 예를 들어 큰 화면은 필요한 경우 일반 크기 화면 리소스를 사용합니다.

그러나 사용 가능한 유일한 리소스가 현재 화면보다 경우 시스템은 리소스를 사용하지 않으며 기기 구성과 일치하는 다른 리소스가 없으면 앱이 비정상 종료됩니다. 예를 들어 모든 레이아웃 리소스에 xlarge 한정자로 태그가 지정되었지만 기기가 일반 크기 화면인 경우에 이러한 상황이 발생합니다.

참고: 한정자의 우선순위(표 2)는 기기에 정확하게 일치하는 한정자의 수보다 중요합니다. 이전 예에서, 4단계에서 목록의 마지막 선택 항목에는 기기와 정확히 일치하는 한정자 3개(방향, 터치스크린 유형, 입력 방법)가 포함되지만 drawable-en에는 일치하는 매개변수가 1개(언어)만 있습니다. 다만 언어가 이러한 다른 한정자보다 우선순위가 높기 때문에 drawable-port-notouch-12key는 제거됩니다.