Android
Resource ID
String
Development
Programming

Android, getting resource ID from string?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To get a resource ID from a string in Android, use getResources().getIdentifier("resource_name", "resource_type", getPackageName()). This method resolves a resource name at runtime and returns its integer ID, or 0 if the resource does not exist. It is the standard approach when you cannot reference a resource through the compile-time R class.

This capability matters in real projects. Dynamic theming, plugin architectures, server-driven UIs, and internationalization workflows all need to resolve resource names that are not known until runtime. Understanding how the Android resource system works under the hood helps you use getIdentifier() effectively and avoid the performance traps that come with it.

How the Android Resource System Works

Android resources live in the res/ directory, organized into typed subdirectories: drawable/, layout/, values/, mipmap/, and others. At build time, the Android Asset Packaging Tool (AAPT2) assigns each resource a unique 32-bit integer ID and writes these IDs into the auto-generated R class.

java
1// Auto-generated R class (simplified)
2public final class R {
3    public static final class string {
4        public static final int app_name = 0x7f0a0001;
5        public static final int welcome_message = 0x7f0a0002;
6    }
7    public static final class drawable {
8        public static final int ic_launcher = 0x7f080001;
9    }
10}

When you write R.string.app_name in your code, the compiler replaces it with the integer constant directly. This is fast because there is no lookup at runtime. The getIdentifier() method exists for the cases where you cannot use this compile-time path.

Using getIdentifier() to Resolve Resource Names

The Resources.getIdentifier() method accepts three parameters and returns the resource ID as an integer.

java
1int resId = getResources().getIdentifier(
2    "welcome_message",   // resource name (without prefix)
3    "string",            // resource type
4    getPackageName()     // package name
5);

The method returns 0 when no matching resource is found. Always check for this before using the ID.

Complete Example in an Activity

java
1public class MainActivity extends AppCompatActivity {
2    @Override
3    protected void onCreate(Bundle savedInstanceState) {
4        super.onCreate(savedInstanceState);
5        setContentView(R.layout.activity_main);
6
7        // Resolve a drawable resource by name
8        String iconName = "ic_settings";
9        int drawableId = getResources().getIdentifier(
10            iconName, "drawable", getPackageName()
11        );
12
13        if (drawableId != 0) {
14            ImageView imageView = findViewById(R.id.icon_view);
15            imageView.setImageResource(drawableId);
16        } else {
17            Log.w("ResourceLookup", "Drawable not found: " + iconName);
18        }
19    }
20}

Kotlin Equivalent

kotlin
1val iconName = "ic_settings"
2val drawableId = resources.getIdentifier(iconName, "drawable", packageName)
3
4if (drawableId != 0) {
5    binding.iconView.setImageResource(drawableId)
6} else {
7    Log.w("ResourceLookup", "Drawable not found: $iconName")
8}

Accessing Resources from Other Packages

When you need a resource from a different package (for example, a system resource), pass that package name as the third argument.

java
1// Get the Android system's "ok" string
2int systemOkId = getResources().getIdentifier(
3    "ok", "string", "android"
4);
5String okText = getString(systemOkId);

Practical Use Cases

Dynamic Theming

When themes are defined as resource sets and the active theme is selected at runtime (perhaps from a remote config), you can resolve color or style resources by name.

java
1String themePrimary = currentTheme + "_primary_color";
2int colorId = getResources().getIdentifier(themePrimary, "color", getPackageName());
3if (colorId != 0) {
4    toolbar.setBackgroundColor(ContextCompat.getColor(this, colorId));
5}

Server-Driven UI

A backend API can send layout element names that the app resolves locally. This avoids shipping image binaries over the network while still letting the server control which assets appear.

java
// Server response contains: {"icon": "promo_banner_july"}
String serverIcon = response.getString("icon");
int iconId = getResources().getIdentifier(serverIcon, "drawable", getPackageName());

Iterating Over Numbered Resources

When resources follow a naming convention like level_1, level_2, etc., you can load them in a loop without listing every ID manually.

java
1List<String> levelNames = new ArrayList<>();
2for (int i = 1; i <= 10; i++) {
3    int id = getResources().getIdentifier("level_" + i, "string", getPackageName());
4    if (id != 0) {
5        levelNames.add(getString(id));
6    }
7}

Performance Comparison

ApproachLookup CostUse When
R.drawable.icon (compile-time)Zero runtime cost, compiled to constantResource name is known at compile time
getIdentifier() (runtime)String-based lookup through resource tableResource name determined at runtime
Cached getIdentifier() resultOne-time lookup cost, then constant accessSame dynamic resource accessed repeatedly

The runtime lookup is measurably slower than a direct R constant. On most devices the difference per call is small (microseconds), but it adds up in tight loops, RecyclerView adapters, or animation frames. Cache the result when you use the same resource name more than once.

java
1// Cache the ID once, reuse it
2private int cachedIconId = -1;
3
4private int getIconId() {
5    if (cachedIconId == -1) {
6        cachedIconId = getResources().getIdentifier(
7            "ic_cached_icon", "drawable", getPackageName()
8        );
9    }
10    return cachedIconId;
11}

Common Pitfalls

  • Not checking for zero. getIdentifier() returns 0 when the resource is not found. Passing 0 to methods like getString() or setImageResource() throws a Resources.NotFoundException at runtime.
  • Wrong resource type string. Passing "Drawable" instead of "drawable" or "str" instead of "string" silently returns 0. The type must match the subdirectory name exactly, in lowercase.
  • Using getIdentifier() in a loop without caching. Each call traverses the resource table. In a RecyclerView.Adapter.onBindViewHolder(), this can cause visible jank. Resolve the IDs once and store them in a map.
  • Relying on getIdentifier() for resources that exist at compile time. If you know the resource name when writing the code, use the R class directly. The compiler can then verify the resource exists, and ProGuard/R8 can optimize the reference.
  • Forgetting resource name changes after refactoring. Because getIdentifier() uses a string, the compiler cannot warn you when a resource is renamed or deleted. This creates silent failures that only surface at runtime.
  • Confusing package name with application ID. In build variants where applicationId differs from the Java package, pass the correct application ID. Using getPackageName() from an Activity or Context returns the right value, but hard-coding a package string can break in flavor builds.

Summary

  • Use getResources().getIdentifier(name, type, package) to resolve a resource ID from a string at runtime.
  • The method returns 0 when the resource is not found. Always guard against this.
  • Prefer compile-time R class references whenever possible. They are faster, type-safe, and verified by the compiler.
  • Cache the result of getIdentifier() when you need the same resource ID more than once.
  • Common use cases include dynamic theming, server-driven UIs, plugin architectures, and iterating over conventionally named resources.
  • Watch for case-sensitive type strings, stale resource names after refactoring, and the difference between package name and application ID in multi-flavor builds.

Course illustration
Course illustration

All Rights Reserved.