Explain Codes LogoExplain Codes Logo

Android, getting resource ID from string?

java
android-development
resource-management
performance-optimization
Anton ShumikhinbyAnton Shumikhin·Sep 8, 2024
TLDR

Obtain a resource ID using getIdentifier() from Android's Resources:

int resId = context.getResources().getIdentifier("name", "type", context.getPackageName());

Here, replace "name" with the name of the resource, and "type" with the type of the resource (like "drawable", "layout", "string"). You can now access the resource programmatically using resId.

But wait, there's more! Keep an eye out for resource field names. They may throw you a curveball with sneaky underscore (_) substitutions for periods (.).

Why not use reflection?

Reflection could be a speedier alternative than getIdentifier(). While it does clock in a quicker runtime, it's also a wee bit more intricate:

Field field = R.drawable.class.getField("resourceName"); int resourceId = field.getInt(null);

Interested in performance comparison? Visit Daniel Lew's blog post. It's an enlightening read!

Watch out for the shrink rays!

Using build tools like ProGuard or R8, code shrinking could sneakily remove unused resources. Ensure to keep these resource entries safe and sound:

-keepclassmembers class **.R$* { public static <fields>; }

Keep your resource entries safe from the shrink rays!

Need for speed? Use a cache.

A static HashMap can act as a cache to speed up repeated resource lookups:

static Map<String, Integer> resourceCache = new HashMap<>(); public static int getResId(String resName, Class<?> c) { if (!resourceCache.containsKey(resName)) { try { Field field = c.getDeclaredField(resName); resourceCache.put(resName, field.getInt(null)); } catch (Exception e) { return -1; } } return resourceCache.get(resName); }

Now we're talking turbo speed, Vin Diesel style!

Here be dragons: Handling exceptions

Make sure to verify resource availability to handle potentially missing resources:

if (resId == 0) { // This resource doesn't exist. It's a Sahara desert out here! }

Basically, if getIdentifier() returns a big fat 0, then sorry mate, that resource doesn't exist!

Package name got you confused?

Ensure the accuracy of the package name when using getIdentifier(). An incorrect package name is like the wrong address, and the postman (in this case, the ID) won't deliver.

Enumerate 'em all!

Consider using an enum that maps resource names to their IDs. It's type safety with a cherry on top, and reduces the chances of making a typo at runtime.