Как получить ID ресурса по имени в Android: динамический доступ
Быстрый ответ
Для получения идентификатора ресурса в Android вы можете использовать метод getIdentifier() класса Resources. Данный метод принимает три параметра: имя ресурса, тип ресурса (к примеру, drawable, string) и имя пакета:
int resId = getResources().getIdentifier("your_resource_name", "resource_type", getPackageName());
Если вы хотите получить ID изображения под именем my_image, которое находится в директории drawable, используйте следующий код:
int drawableId = getResources().getIdentifier("my_image", "drawable", getPackageName());
Этот фрагмент кода вернет желаемый идентификатор ресурса или 0, в случае, если ресурс не будет найден.

Особенности использования и сценарии применения
Методом getIdentifier() следует пользоваться аккуратно, т.к. есть свои ограничения и рекомендован для определенных ситуаций:
- Нагрузка на выполнение: Метод может создавать дополнительную нагрузку из-за процесса поиска ресурсов. По этой причине, он не является лучшим выбором для кода, который выполняется часто, например, в анимации или при отрисовке интерфейса.
- Проверка на существование ресурсов: Не стоит забывать проверять, что результат выполнения вызова не равен нулю, так как это указывает на отсутствие ресурса. Использование такого ID может привести к исключению
Resources.NotFoundException. - Ошибки в названиях и рефакторинге: Компилятор Java не будет в состоянии указать вам на ошибки в именах ресурсов, также он не обновит эти имена автоматически, если будет использоваться
getIdentifier(). - Квалифицированные ресурсы: Если вы работаете с ресурсами, которые содержат квалификаторы (язык, ориентация и пр.), нужно помнить, что
getIdentifier()их не обрабатывает и потребуется добавить дополнительную логику для управления такими ресурсами.
Используйте getIdentifier() с осторожностью, чтобы найти оптимальный баланс между гибкостью и производительностью приложения.
Оптимизация применения getIdentifier()
getIdentifier() — многофункциональный инструмент, и есть несколько способов его оптимизации:
- Кэширование ID: Для часто используемых ID стоит разместить их в кэше с помощью
HashMap. - Расширения Kotlin: Если вы программируете на Kotlin, создайте функции-расширения для упрощения вызова
getIdentifier(). - Аннотации ресурсов: Применяйте аннотации ресурсов Android, такие как
@DrawableRes,@StringRes, для обеспечения безопасности типов и исключения ошибок, связанных с типами. - Правила Proguard: Убедитесь, что Proguard не удаляет важные ресурсы, используемые с
getIdentifier(), указывая их в конфигурации Proguard.
Визуализация
Давайте представим процесс получения идентификатора ресурса по имени как визит в библиотеку:
Библиотека (📚): Вы знаете НАЗВАНИЕ нужной книги.
int resourceId = context.getResources().getIdentifier("name_of_resource", "type_of_resource", context.getPackageName());
В описанных аналогиях это будет выглядеть так:
Вы (🤔): "Библиотекарь, у вас есть книга с названием 'name_of_resource'?"
Библиотекарь (👩💼): "Да, вот она, книга 'type_of_resource' с идентификатором 123."
Идентификатор ресурса (🆔) — это уникальный номер, который дает библиотекарь (в нашем случае — Android), давая вам доступ к нужному ресурсу.
Размышления о возможных альтернативах
В случае постоянного набора ресурсов иногда более эффективен применять java.lang.reflect:
- Поиск класса R: Найдите класс
Rи его вложенные классы в зависимости от типа (drawable,stringи др.). - Доступ к полю: Открытйе доступ к полю через класс и извлечьте из него идентификатор с помощью
getInt(null). - Обработка ошибок: Рефлексия вызывает исключение
NoSuchFieldExceptionпри ошибке в имени ресурса, это аналогично неправильному вызовуgetIdentifier().
Пример использования данного подхода:
try {
Class res = R.drawable.class;
Field field = res.getField("my_image");
int drawableId = field.getInt(null);
} catch (Exception e) {
e.printStackTrace();
}
Рефлексия обладает большей скоростью выполнения по сравнению с getIdentifier() за счет отсутствия поиска во время выполнения, но может быть менее понятной и предсказуемой.
Работа с ресурсами на уровне группы
При работе с группами ресурсов можно применить следующие методы:
- Использование цикла с getIdentifier(): Если ваши ресурсы следуют определенным правилам именования, можно организовать цикл для получения ID каждого ресурса с помощью
getIdentifier(). - Массивы и XML-файлы: Создавайте массив имен ресурсов в XML и перебирайте их в цикле, либо используйте
getIdentifier(), когда требуется динамическое управление ресурсами.
Полезные материалы
- Обзор ресурсов приложения – Документация Android – Управление ресурсами в Android.
- Stack Overflow – Получение идентификатора ресурса по его имени – Обсуждения на Stack Overflow о получении идентификаторов ресурсов.
- Динамическая локализация ресурсов в Android – Учебное руководство по реализации локализации в Android.
- Доступ к ресурсам в Android – Документация Android – Информация по работе с различными типами ресурсов.
- Учебник по рефлексии в Java – Oracle – Руководство Oracle по использованию рефлексии в Java.


