Обзор ресурсов приложения

Ресурсы – это дополнительные файлы и статический контент, используемые кодом, например растровые изображения, строки пользовательского интерфейса, инструкции по анимации и т. д.

Всегда выносите ресурсы приложения, такие как изображения и строки, за пределы кода, чтобы иметь возможность работать с ними отдельно. Также предоставьте альтернативные ресурсы для определенных конфигураций устройств, сгруппировав их в каталогах ресурсов со специальными названиями. Во время выполнения Android использует подходящий ресурс в зависимости от текущей конфигурации. Например, вы можете использовать разные строки в зависимости от языковых настроек.

После этого вы сможете обращаться к ним, используя идентификаторы ресурсов, которые генерируются в классе R вашего проекта. В этом документе показано, как группировать ресурсы в проекте для Android. Также вы узнаете, как предоставлять альтернативные ресурсы для определенных конфигураций устройств и получать к ним доступ из кода приложения или других XML-файлов.

Типы ресурсов группы

Поместите каждый тип ресурса в определенный подкаталог каталога res/ вашего проекта. Вот как выглядит иерархия файлов для простого проекта:

MyProject/
    src/
        MyActivity.kt
    res/
        drawable/
            graphic.png
        mipmap/
            icon.png
        values/
            strings.xml

Каталог res/ содержит все ресурсы в своих подкаталогах: графический ресурс, каталог mipmap/ для значков приложения и файл строкового ресурса. Названия каталогов ресурсов важны и описаны в таблице 1.

Примечание. Подробнее о том, как использовать папки mipmap, рассказывается в статье Как разместить значки приложения в каталогах mipmap.

Таблица 1. Каталоги ресурсов поддерживаются в каталоге проекта res/.

Каталог Тип ресурса
drawable/

Растровые файлы (PNG, .9.png, JPG или GIF) или XML-файлы, которые компилируются в следующие подтипы прорисовываемых ресурсов:

  • Растровые файлы
  • Nine-patch (масштабируемые растровые изображения)
  • Списки штатов
  • Фигуры
  • Анимированные графические объекты
  • Другие графические объекты

Подробнее о прорисовываемых ресурсах…

mipmap/ Файлы Drawable для значков приложений с разной плотностью пикселей. Дополнительную информацию об управлении значками приложений с помощью папок mipmap/ можно найти в статье Как разместить значки приложений в каталогах mipmap.
raw/

Произвольные файлы, которые нужно сохранить в исходном виде. Чтобы открыть эти ресурсы с помощью необработанного InputStream, вызовите Resources.openRawResource с идентификатором ресурса R.raw.filename.

Однако если вам нужен доступ к исходным названиям файлов и иерархии файлов, сохраняйте ресурсы в каталоге assets/, а не res/raw/. Файлам в assets/ не присваивается идентификатор ресурса, поэтому их можно только читать с помощью AssetManager.

values/

XML-файлы, содержащие простые значения, такие как строки, целые числа и цвета.

В то время как XML-файлы ресурсов в других подкаталогах res/ определяют один ресурс на основе имени XML-файла, файлы в каталоге values/ описывают несколько ресурсов. Каждый дочерний элемент <resources> в файле из этого каталога определяет один ресурс. Например, элемент <string> создает ресурс R.string, а элемент <color> – ресурс R.color.

Поскольку каждый ресурс определяется собственным XML-элементом, вы можете назвать файл как угодно и поместить в него ресурсы разных типов. Однако для ясности вы можете поместить уникальные типы ресурсов в разные файлы. Ниже приведены примеры названий файлов для ресурсов, которые можно создать в этом каталоге.

Подробнее о строковых ресурсах, ресурсах стилей и других типах ресурсов…

xml/ Произвольные XML-файлы, которые можно прочитать во время выполнения, вызвав Resources.getXML. Здесь должны быть сохранены различные XML-файлы конфигурации.
font/ Файлы шрифтов с расширениями TTF, OTF или TTC, а также XML-файлы, содержащие элемент <font-family>. Подробнее о том, как добавить шрифт в качестве XML-ресурса…

Внимание! Никогда не сохраняйте файлы ресурсов непосредственно в каталоге res/. Это вызывает ошибку компилятора.

Ресурсы, которые вы сохраняете в подкаталогах, указанных в таблице 1, являются ресурсами по умолчанию. Эти ресурсы определяют дизайн и контент приложения по умолчанию. Однако для разных типов устройств Android могут потребоваться разные типы ресурсов.

Например, вы можете предоставить разные строковые ресурсы, которые переводят текст в пользовательском интерфейсе в зависимости от языковых настроек устройства.

Примечание. В Compose пользовательские интерфейсы, анимация и цвета, зависящие от состояния, объявляются в Kotlin, поэтому каталоги layout/, menu/, anim/, animator/ и color/ устарели для современных приложений. Дополнительную информацию можно найти в статьях Анимация в Compose и Анатомия темы в Compose.

Предоставьте альтернативные ресурсы

В большинстве приложений есть альтернативные ресурсы для поддержки определенных конфигураций устройств. Например, добавьте альтернативные прорисовываемые ресурсы для экранов с разной плотностью пикселей и альтернативные строковые ресурсы для разных языков. Во время выполнения Android определяет текущую конфигурацию устройства и загружает соответствующие ресурсы для вашего приложения.

Чтобы указать альтернативные ресурсы для определенной конфигурации, выполните следующие действия:

  1. Создайте в каталоге res/ новый каталог с названием в формате <resources_name>-<qualifier>.
    • <resources_name> – название каталога соответствующих ресурсов по умолчанию (определено в таблице 1).
    • <qualifier> – название, которое указывает на отдельную конфигурацию, для которой должны использоваться эти ресурсы (определено в таблице 2).

    Вы можете добавить несколько параметров <qualifier>. Разделяйте их дефисом.

    Внимание! Если вы добавляете несколько модификаторов, они должны быть указаны в том же порядке, что и в таблице 2. Если модификаторы указаны в неправильном порядке, ресурсы игнорируются.

  2. Сохраните в нем нужные альтернативные ресурсы. Названия файлов ресурсов должны точно совпадать с названиями файлов ресурсов по умолчанию.

Вот примеры ресурсов по умолчанию и альтернативных ресурсов:

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

Модификатор hdpi указывает, что ресурсы в этом каталоге предназначены для устройств с экраном с высоким разрешением. Изображения в этих каталогах drawable имеют размеры, соответствующие определенной плотности экрана, но названия файлов абсолютно одинаковы. Таким образом, идентификатор ресурса, который вы используете для ссылки на изображение icon.png или background.png, всегда будет одинаковым. Android выбирает версию каждого ресурса, которая лучше всего подходит для текущего устройства, сравнивая информацию о конфигурации устройства с квалификаторами в имени каталога ресурсов.

Внимание! При определении альтернативного ресурса убедитесь, что вы также определили ресурс в конфигурации по умолчанию. В противном случае при изменении конфигурации устройства могут возникнуть исключения во время выполнения. Например, если вы добавите строку только в values-en, но не в values, то при изменении пользователем языка системы по умолчанию в приложении может возникнуть исключение Resource Not Found.

В таблице 2 квалификаторы конфигурации перечислены в порядке приоритета. Вы можете добавить несколько модификаторов к одному названию каталога, разделив их дефисом. Если вы используете несколько модификаторов для каталога ресурсов, их нужно добавлять в название каталога в том порядке, в котором они перечислены в таблице.

Таблица 2. Названия квалификаторов конфигурации.

Конфигурация Значения квалификаторов Описание
MCC и MNC Примеры:
mcc310
mcc310-mnc004
mcc208-mnc00

Код MCC, за которым может следовать код MNC с SIM-карты устройства. Например, mcc310 – это США (любой оператор), mcc310-mnc004 – США (Verizon), а mcc208-mnc00 – Франция (Orange).

Если устройство использует радиосвязь (например, это телефон GSM), значения MCC и MNC берутся из SIM-карты.

Вы также можете использовать только MCC, например чтобы добавить в приложение юридические ресурсы для определенной страны. Если вам нужно указать только язык, используйте модификатор язык, письменность (необязательно) и регион (необязательно). Если вы используете модификаторы MCC и MNC, делайте это осторожно и проверяйте, правильно ли они работают.

Также обратите внимание на поля конфигурации mcc и mnc, в которых указаны текущие коды MCC и мобильной сети.

Язык, письменность (необязательно) и регион (необязательно) Примеры:
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, который предоставляет определенный список языковых стандартов. В этот список входит основной язык.

Грамматический род masculine
feminine
neuter

Грамматический род пользователя. Используется для языков, в которых есть грамматический род.

Например, если вам нужно предоставить разные ресурсы для франкоязычных пользователей, вы можете использовать следующие каталоги:

res/
  values-fr/
    strings.xml (строки по умолчанию с неуказанным родом)
  values-fr-masculine/
    strings.xml (строки с мужским родом)
  values-fr-feminine/
    strings.xml (строки с женским родом)
  values-fr-neuter/
    strings.xml (строки со средним родом)

Подробнее о том, как персонализировать интерфейс приложения с помощью грамматического рода…

Также ознакомьтесь с методом настройки getGrammaticalGender, который указывает грамматический род.

Добавлено в API уровня 34.

Широкая цветовая гамма widecg
nowidecg
  • widecg – дисплеи с широкой цветовой гаммой, например Display P3 или AdobeRGB.
  • nowidecg – дисплеи с узкой цветовой гаммой, например sRGB.

Добавлено в API уровня 26.

Также ознакомьтесь с методом конфигурации isScreenWideColorGamut, который позволяет определить, поддерживает ли экран широкую цветовую гамму.

Расширенный динамический диапазон (HDR) highdr
lowdr
  • highdr – дисплеи с расширенным динамическим диапазоном;
  • lowdr – дисплеи с низким или стандартным динамическим диапазоном;

Добавлено в API уровня 26.

Также ознакомьтесь с методом конфигурации isScreenHdr, который позволяет узнать, поддерживает ли экран HDR.

Режим интерфейса car
desk
television
appliance
watch
vrheadset
  • car – устройство подключено к автомобильной док-станции;
  • desk: устройство подключено к настольной док-станции.
  • television – устройство подключено к телевизору, то есть интерфейс отображается на большом экране, который находится далеко от пользователя. Взаимодействие с устройством происходит в основном с помощью d-pad или других средств, не являющихся указателями.
  • appliance: устройство используется как бытовой прибор без дисплея.
  • watch: устройство с дисплеем, которое носят на запястье.
  • vrheadset – устройство показывает контент в очках виртуальной реальности.

Добавлено в API уровня 8; television – в API уровня 13; appliance – в API уровня 16; watch – в API уровня 20; vrheadset – в API уровня 26.

Информацию о том, как приложение может реагировать на подключение устройства к док-станции или отключение от нее, можно найти в статье Как определить и отслеживать тип и состояние док-станции.

Это может измениться в течение срока службы вашего приложения, если пользователь поместит устройство в док-станцию. Некоторые из этих режимов можно включить или отключить с помощью UiModeManager. Подробнее о том, как это влияет на приложение во время выполнения, рассказывается в статье Обработка изменений конфигурации.

Ночной режим night
notnight
  • night: ночное время
  • notnight: день

Добавлено в API уровня 8.

Если в приложении включен автоматический ночной режим (по умолчанию), то он будет активироваться в зависимости от времени суток. Включить или отключить этот режим можно с помощью UiModeManager. Подробнее о том, как это влияет на работу приложения…

Плотность пикселей экрана (DPI) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi – экраны с низким разрешением (около 120 DPI).
  • mdpi: экраны со средней плотностью (на традиционных HVGA); примерно 160 DPI.
  • hdpi: экраны с высоким разрешением (около 240 DPI).
  • xhdpi: экраны со сверхвысоким разрешением (около 320 DPI). Добавлено в API уровня 8.
  • xxhdpi: экраны со сверхвысоким разрешением (около 480 DPI). Добавлено в API уровня 16.
  • xxxhdpi – сверхвысокая плотность (только для значка приложения, см. раздел Поддержка экранов с разной плотностью пикселей); примерно 640 dpi. Добавлено в API уровня 18.
  • nodpi – используется для ресурсов битовых карт, которые не нужно масштабировать в соответствии с плотностью пикселей на экране устройства.
  • tvdpi: экраны с плотностью пикселей между mdpi и hdpi (примерно 213 dpi). Эта группа не считается основной. В основном он предназначен для телевизоров с разрешением 720p и не нужен большинству приложений. Для телевизоров с разрешением 1080p используйте xhdpi, а для телевизоров с разрешением 4K – xxxhdpi. Добавлено в API уровня 13.
  • anydpi – соответствует всем плотностям экрана и имеет приоритет над другими модификаторами. Это полезно для классов VectorDrawable. Добавлено в API уровня 21.
  • nnndpi – используется для нестандартных плотностей, где nnn – положительное целое число. В большинстве случаев этот параметр не используется. Использование стандартных групп плотности значительно снижает затраты на поддержку различных плотностей экранов устройств, представленных на рынке.

Для шести основных плотностей (без учета tvdpi) используется соотношение 3:4:6:8:12:16. Например, битовая карта размером 9 x 9 в ldpi будет иметь размер 12 x 12 в mdpi, 18 x 18 в hdpi, 24 x 24 в xhdpi и т. д.

Примечание. Использование квалификатора разрешения не означает, что ресурсы предназначены только для экранов с таким разрешением. Если вы не предоставите альтернативные ресурсы с модификаторами, которые лучше соответствуют текущей конфигурации устройства, система будет использовать ресурсы, которые подходят лучше всего.

Дополнительную информацию о том, как работать с экранами разной плотности и как Android может масштабировать растровые изображения в соответствии с текущей плотностью, можно найти в обзоре совместимости экранов.

Тип сенсорного экрана notouch
finger
  • notouch: на устройстве нет сенсорного экрана.
  • finger – устройство оснащено сенсорным экраном, предназначенным для непосредственного взаимодействия с пальцем пользователя.

Также обратите внимание на поле конфигурации touchscreen, в котором указан тип сенсорного экрана на устройстве.

Доступность клавиатуры keysexposed
keyshidden
keyssoft
  • keysexposed: на устройстве есть клавиатура. Если на устройстве включена виртуальная клавиатура (что вполне вероятно), она используется, даже если аппаратная клавиатура не доступна пользователю или отсутствует. Если виртуальная клавиатура не предусмотрена или отключена, то этот параметр используется только при наличии аппаратной клавиатуры.
  • keyshidden – на устройстве есть аппаратная клавиатура, но она скрыта, и на устройстве не включена виртуальная клавиатура.
  • keyssoft – на устройстве включена виртуальная клавиатура (независимо от того, видна ли она).

Если вы предоставите ресурсы keysexposed, но не keyssoft, система будет использовать ресурсы keysexposed независимо от того, видна ли клавиатура, если в системе включена виртуальная клавиатура.

Это значение может измениться, если пользователь подключит аппаратную клавиатуру. Подробнее о том, как это влияет на работу приложения…

Также обратите внимание на поля конфигурации hardKeyboardHidden и keyboardHidden, которые указывают на видимость аппаратной клавиатуры и клавиатуры любого типа (включая программную) соответственно.

Основной способ ввода текста 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 поддерживают все модификаторы. При использовании нового квалификатора неявно добавляется квалификатор версии платформы, чтобы старые устройства могли его игнорировать. Чтобы избежать проблем, всегда включайте набор ресурсов по умолчанию (набор ресурсов без квалификаторов). Подробнее о том, как обеспечить совместимость ресурсов с разными устройствами…

В приложениях Compose квалификаторы конфигурации, связанные с макетом и размерами, не нужны. Они по-прежнему существуют, но не включены в таблицу 2. К таким модификаторам относятся: направление макета, наименьшая ширина, доступная ширина, доступная высота, размер экрана, соотношение сторон экрана, круглый экран и ориентация экрана. Полный список квалификаторов конфигурации в порядке приоритета приведен в статье Обзор ресурсов приложения (представления).

Правила для названий модификаторов

Вот несколько правил, которые нужно соблюдать при использовании квалификаторов конфигурации:

  • Для одного набора ресурсов можно указать несколько модификаторов, разделенных дефисами. Например, drawable-en-rUS-night применяется к устройствам с американским английским языком в ночном режиме.
  • Модификаторы должны быть указаны в порядке, приведенном в таблице 2.
    • Неправильно: drawable-hdpi-night/
    • Правильно: drawable-night-hdpi/
  • Каталоги альтернативных ресурсов не могут быть вложенными. Например, нельзя использовать res/drawable/drawable-en/.
  • Значения указываются без учета регистра. Компилятор ресурсов преобразует названия каталогов в нижний регистр перед обработкой, чтобы избежать проблем в файловых системах без учета регистра. Прописные буквы в названиях используются только для удобства чтения.
  • Для каждого типа модификатора поддерживается только одно значение. Например, если вы хотите использовать одни и те же графические файлы для Испании и Франции, вы не можете создать каталог с названием drawable-es-fr/. Вместо этого вам нужно создать два каталога ресурсов, например drawable-es/ и drawable-fr/, которые содержат соответствующие файлы.

После того как вы сохраните альтернативные ресурсы в каталогах, названных с использованием этих модификаторов, Android автоматически применит ресурсы в вашем приложении на основе текущей конфигурации устройства. Каждый раз, когда запрашивается ресурс, Android проверяет альтернативные каталоги ресурсов, содержащие запрошенный файл ресурса, а затем находит наиболее подходящий ресурс.

Если альтернативных ресурсов, соответствующих определенной конфигурации устройства, нет, Android использует ресурсы по умолчанию – набор ресурсов определенного типа, не включающий квалификатор конфигурации.

Как создать псевдонимы ресурсов

Если вы хотите использовать ресурс для нескольких конфигураций устройства, но не хотите, чтобы он был ресурсом по умолчанию, вам не нужно помещать его в несколько каталогов альтернативных ресурсов. Вместо этого вы можете создать альтернативный ресурс, который будет действовать как псевдоним для ресурса, сохраненного в каталоге ресурсов по умолчанию.

Объекты Drawable

Например, у вас есть значок приложения icon.png и вам нужны его уникальные версии для разных регионов. Однако для двух локалей (английской и французской в Канаде) нужно использовать одну и ту же версию. Вам не нужно копировать одно и то же изображение в каталог ресурсов для английского и французского языков в Канаде. Вместо этого вы можете сохранить изображение, которое используется для обоих вариантов, под любым названием, кроме icon.png, например icon_ca.png, и поместить его в каталог res/drawable/ по умолчанию. Затем создайте файл icon.xml в каталогах res/drawable-en-rCA/ и res/drawable-fr-rCA/, который ссылается на ресурс icon_ca.png с помощью элемента <bitmap>.

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

Это позволяет хранить только одну версию PNG-файла и два небольших XML-файла, которые указывают на него. Затем вы можете использовать painterResource(R.drawable.icon), и система выберет подходящий файл, как только определит региональные настройки.

Строки и другие простые значения

Чтобы создать псевдоним для существующей строки, используйте идентификатор ресурса нужной строки в качестве значения для новой строки:

<?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>

Доступ к ресурсам приложения

После того как вы добавите ресурс в приложение, вы сможете использовать его, указав его идентификатор. Все идентификаторы ресурсов определены в классе R проекта, который автоматически генерируется инструментом aapt.

При компиляции приложения aapt генерирует класс R, который содержит идентификаторы всех ресурсов в каталоге res/. Для каждого типа ресурса есть подкласс R, например R.drawable для всех прорисовываемых ресурсов. Для каждого ресурса этого типа есть статическое целое число, например R.drawable.icon. Это целое число является идентификатором ресурса, который можно использовать для получения ресурса.

Хотя идентификаторы ресурсов указываются в классе R, вам не нужно искать их там. Идентификатор ресурса всегда состоит из следующих элементов:

  • Тип ресурса. Каждый ресурс относится к определенному типу, например string или drawable.
  • Название ресурса, которое совпадает с названием файла без расширения.

Как получить доступ к ресурсам в Compose

В Jetpack Compose есть встроенные функции, которые учитывают composable-функции и обеспечивают безопасный доступ к ресурсам.

  • Строки:
    stringResource(id = R.string.hello)
  • Графические объекты:
    painterResource(id = R.drawable.my_icon)

Доступ к ресурсам в коде, не связанном с интерфейсом

Если вам нужно получить доступ к ресурсам за пределами иерархии пользовательского интерфейса, например в ViewModel, Repository или системном Service, вы можете использовать Context.

// Retrieve a localized string resource
val greeting = context.getString(R.string.hello_world)

Вы также можете получать отдельные ресурсы с помощью методов в Resources, экземпляр которого можно получить с помощью getResources.

Синтаксис

Вот синтаксис для ссылки на ресурс в коде:

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name> – название пакета, в котором находится ресурс (не требуется, если вы ссылаетесь на ресурсы из собственного пакета).
  • <resource_type> – подкласс R для типа ресурса.
  • <resource_name> – это название файла ресурса без расширения или значение атрибута android:name в элементе XML для простых значений.

Дополнительную информацию о каждом типе ресурсов и о том, как на них ссылаться, см. в разделе Ресурсы в Compose.

Доступ к исходным файлам

В редких случаях вам может потребоваться доступ к исходным файлам и каталогам. Если да, то сохранение файлов в res/ вам не подойдет, поскольку единственный способ прочитать ресурс из res/ – использовать идентификатор ресурса. Вместо этого вы можете сохранить ресурсы в каталоге assets/.

Файлам, сохраненным в каталоге assets/, не присваивается идентификатор ресурса, поэтому вы не можете ссылаться на них через класс R или из XML-ресурсов. Вместо этого вы можете запрашивать файлы в каталоге assets/, как в обычной файловой системе, и читать первичные данные с помощью AssetManager.

Однако если вам нужно только прочитать первичные данные (например, видео- или аудиофайл), сохраните файл в каталоге res/raw/ и прочитайте поток байтов с помощью openRawResource.

Доступ к ресурсам платформы

В Android есть ряд стандартных ресурсов, например системные стили и темы. Чтобы получить к ним доступ, укажите класс пакета android в ссылке на ресурс. Пример: painterResource(android.R.drawable.ic_menu_info_details).

Обеспечьте совместимость ресурсов с разными устройствами

Чтобы приложение поддерживало несколько конфигураций устройств, очень важно всегда предоставлять ресурсы по умолчанию для каждого типа ресурсов, используемых вашим приложением.

Например, если ваше приложение поддерживает несколько языков, всегда включайте каталог values/ (в котором хранятся строки) без модификатора языка и региона. Если же вы поместите все файлы со строками в каталоги с модификаторами языка и региона, то приложение будет аварийно завершать работу на устройствах, где выбран язык, который не поддерживается вашими строками.

Если вы предоставите ресурсы по умолчанию,values/ приложение будет работать правильно, даже если пользователь не понимает язык, на котором оно представлено. Это лучше, чем разбиться.

Предоставлять ресурсы по умолчанию важно не только потому, что ваше приложение может работать в непредвиденной конфигурации, но и потому, что в новых версиях Android иногда добавляются квалификаторы конфигурации, которые не поддерживаются более ранними версиями. Если вы используете новый квалификатор ресурса, но сохраняете совместимость кода с более ранними версиями Android, то при запуске приложения на устройстве с более ранней версией Android оно будет аварийно завершать работу, если вы не предоставите ресурсы по умолчанию, поскольку оно не сможет использовать ресурсы, названные с помощью нового квалификатора.

Например, если для minSdkVersion задано значение 4, а вы используете для всех прорисовываемых ресурсов ночной режим (night или notnight, добавленные в уровень API 8), то устройство с уровнем API 4 не сможет получить доступ к этим ресурсам и произойдет сбой. В этом случае вам, скорее всего, нужно, чтобы ресурсы notnight использовались по умолчанию. Для этого исключите модификатор и поместите прорисовываемые ресурсы в папку drawable/ или drawable-night/.

Проще говоря, чтобы обеспечить наилучшую совместимость устройств, всегда предоставляйте ресурсы по умолчанию для ресурсов, необходимых вашему приложению для правильной работы. Затем создайте альтернативные ресурсы для определенных конфигураций устройств, используя квалификаторы конфигурации.

Есть одно исключение: если значение minSdkVersion вашего приложения равно 4 или больше, вам не нужны прорисовываемые ресурсы по умолчанию, если вы предоставляете альтернативные прорисовываемые ресурсы с квалификатором разрешения экрана. Даже без прорисовываемых ресурсов по умолчанию Android может найти наилучшее соответствие среди альтернативных плотностей экрана и масштабировать растровые изображения по мере необходимости. Однако для наилучшего отображения на всех типах устройств предоставьте альтернативные графические объекты для всех трех типов плотности.

Как Android находит наиболее подходящий ресурс

Когда вы запрашиваете ресурс, для которого указаны альтернативные варианты, Android выбирает, какой из них использовать во время выполнения, в зависимости от текущей конфигурации устройства. Чтобы продемонстрировать, как Android выбирает альтернативный ресурс, предположим, что следующие каталоги drawable содержат разные версии одних и тех же изображений:

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

Предположим, что конфигурация устройства выглядит следующим образом:

Региональные настройки = en-GB
Ночной режим = night
Плотность пикселей экрана = hdpi
Тип сенсорного экрана = notouch
Основной способ ввода текста = 12key

Сравнив конфигурацию устройства с доступными альтернативными ресурсами, Android выбирает графические объекты из папки drawable-en-night.

Система выбирает ресурсы по следующей логике:

Рисунок 2. Блок-схема, показывающая, как Android находит наиболее подходящий ресурс.

  1. Удалите файлы ресурсов, которые противоречат конфигурации устройства.

    Каталог drawable-fr-rCA/ исключается, так как он противоречит региональным настройкам en-GB.

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

    Исключение. Плотность пикселей экрана – это единственный квалификатор, который не исключается из-за противоречия. Хотя разрешение экрана устройства – hdpi, drawable-night-ldpi/ не исключается, поскольку на этом этапе все разрешения считаются подходящими. Подробнее о совместимости экранов…

  2. Найдите в списке следующий по приоритету модификатор (таблица 2). (Начните с MCC.)
  3. Содержит ли какой-либо из каталогов ресурсов этот квалификатор?
    • Если нет, вернитесь к шагу 2 и посмотрите на следующий квалификатор. В этом примере ответ "нет" до тех пор, пока не будет достигнут квалификатор языка.
    • Если да, перейдите к шагу 4.
  4. Удалите каталоги ресурсов, которые не содержат этот квалификатор. В этом примере система исключает все каталоги, в которых нет квалификатора языка:
    drawable/
    drawable-en/
    drawable-en-night/
    drawable-en-notouch-12key/
    drawable-night-ldpi/
    drawable-night-notouch-12key/
    

    Исключение. Если модификатор – это плотность пикселей экрана, Android выбирает вариант, который наиболее точно соответствует плотности пикселей экрана устройства. Как правило, Android предпочитает уменьшать размер большого исходного изображения, а не увеличивать размер маленького исходного изображения. Подробнее о совместимости экранов…

  5. Повторяйте шаги 2, 3 и 4, пока не останется только один каталог. В этом примере ночной режим – следующий модификатор, для которого есть совпадения. Ресурсы, для которых не указан ночной режим, исключаются:
    drawable-en/
    drawable-en-night/
    drawable-en-notouch-12key/
    

    Оставшийся каталог – drawable-en-night.

Хотя эта процедура выполняется для каждого запрашиваемого ресурса, система оптимизирует некоторые ее аспекты. Например, когда конфигурация устройства известна, можно исключить альтернативные ресурсы, которые никогда не будут соответствовать. Например, если в конфигурации выбран английский язык, то любой каталог ресурсов, в котором квалификатор языка имеет значение, отличное от английского, никогда не включается в пул проверяемых ресурсов (хотя каталог ресурсов без квалификатора языка все равно включается).

При выборе ресурсов на основе модификаторов размера экрана система использует ресурсы, предназначенные для экрана меньшего размера, чем текущий, если нет ресурсов, которые подходят лучше. Например, для большого экрана при необходимости используются ресурсы обычного экрана.

Однако если доступные ресурсы больше текущего экрана, система не будет их использовать, и приложение завершит работу со сбоем, если другие ресурсы не соответствуют конфигурации устройства. Например, это происходит, если все ресурсы разметки помечены квалификатором xlarge, а устройство имеет экран обычного размера.

Примечание. Приоритет модификатора (в таблице 2) важнее, чем количество модификаторов, которые точно соответствуют устройству. В предыдущем примере на четвертом шаге последний вариант в списке включает три квалификатора, которые точно соответствуют устройству (ночной режим, тип сенсорного экрана и метод ввода), в то время как drawable-en имеет только один соответствующий параметр (язык). Однако язык имеет более высокий приоритет, чем другие модификаторы, поэтому drawable-night-notouch-12key исключается.

Дополнительные ресурсы

Дополнительную информацию о ресурсах приложения можно найти по следующим ссылкам:

Документация

Просмотр контента