How to get a resource id with a known resource name?
Fetch a resource ID in Android by invoking the getIdentifier()
method of the Resources
class. You need to pass the resource name, resource type (e.g. drawable
, string
), and your package name:
For instance, if you have an image called my_image
in drawable
, to retrieve its ID:
This single line of code provides the desired resource ID or returns 0
if the resource doesn't exist.
Cautions and use-case scenarios
The getIdentifier()
method, while mighty, comes with certain caveats and is suitable within specific scenarios:
- Runtime Overhead: It incurs significant runtime overhead due to the lookup. Hence, it isn't best suited for areas of your code that run frequently, like animations or layout drawing.
- Handle Non-existent Resources: Always ensure the return value is non-zero since a zero indicates non-existent resources. Using this ID can result in
Resources.NotFoundException
. - Misspellings and Refactoring: The compiler won't flag typos in resource names and won't update the strings automatically when using
getIdentifier()
. - Qualified Resources: When dealing with resources with qualifiers (language, orientation, etc.), remember that
getIdentifier()
doesn't handle them. You would need to manage qualifiers within the resource name.
It's vital to use getIdentifier()
judiciously to strike a balance between flexibility and app performance.
Optimizing getIdentifier() usage
While getIdentifier()
is exceptionally versatile, here are several tips to optimize its usage:
-
Caching IDs: Consider caching IDs when used frequently throughout the application, a
HashMap
would be a suitable solution here. -
Kotlin Extension Functions: Leverage Kotlin's features and write an extension function to streamline the use of
getIdentifier()
. -
Resource Annotations: Use Android's resource annotations such as
@DrawableRes
,@StringRes
to ensure type safety and avoid sending incorrect types. -
Proguard Rules: Ensure ProGuard does not obfuscate or remove the resources accessed with
getIdentifier()
, by stating these resource names explicitly in rules.
Reflecting on alternatives
When dealing with a fixed set of known resources, java.lang.reflect
might be more efficient:
-
Class Lookup: Fetch the
R
class and then the nested class representing the type (drawable
,string
etc.). -
Field Access: Get the
Field
from the class and derive the actual integer ID usinggetInt(null)
. -
Error Handling: Reflection throws
NoSuchFieldException
for wrong resource names, which is noticed at runtime, similar to a failedgetIdentifier()
call.
Below is a simple snippet:
While reflection seems a bit complex, it's faster than getIdentifier()
, mainly because it dodges runtime name lookups, but it's a tad less predictable and readable.
Group-level resource handling
When working with groups of resources like animations or a series of images, you might need to fetch multiple IDs. Here are some tips:
-
Loop with getIdentifier(): If your resources follow a naming convention, you can loop through them and call
getIdentifier()
for each name. -
Arrays or XML Resource Files: Define an array of resource names in XML and loop through them; this can be done either directly using resource IDs or using
getIdentifier()
when dynamic control is needed.
Was this article helpful?