Skip to content

Look up Android image resources without throwing an exception - #59456

Open
hryhoriiK97 wants to merge 1 commit into
react:mainfrom
hryhoriiK97:android-resource-drawable-id-without-exception
Open

hryhoriiK97 wants to merge 1 commit into
react:mainfrom
hryhoriiK97:android-resource-drawable-id-without-exception

Conversation

@hryhoriiK97

Copy link
Copy Markdown
Contributor

Summary:

In Release builds on Android, an image from the bundle (<Image source={require('./icon.png')} />) is a drawable resource, and its source is the resource name, for example assets_icon. ImageSource turns that name into a URI with ResourceDrawableIdHelper.getResourceDrawableId. The same lookup runs for defaultSource and loadingIndicatorSource, Image.getSize of a bundled image, and TextInput's inlineImageLeft. Images loaded from Metro or from a bundle outside the APK have a URI scheme and don't use it.

Current behavior. getResourceDrawableId first tries the name as a numeric resource id with toInt() and catches the NumberFormatException. Resource names are not numbers, so every such image source throws an exception and fills in a stack trace as deep as the mount call stack. This happens before the cache of looked-up names, so names that were already looked up throw too. On a Samsung Galaxy A14 the lookup takes about 0.24 ms for each image source, almost all of it in the exception.

With this change. The name is parsed with toIntOrNull(), which accepts the same numbers as toInt() and returns null instead of throwing. Numeric names still return the same id, and other names are still looked up as drawables, so every name gives the same result as before.

Changelog:

[ANDROID] [CHANGED] - Images from the app bundle look up their resource without throwing an exception

Test Plan:

  • The pinned ktfmt (--dry-run --set-exit-if-changed) passes on both files.
  • Added ResourceDrawableIdHelperTest (5 tests: empty name, numeric names, a name looked up as a drawable after normalization, a number too big for an Int, an unknown name). It passes with this change and with the old code, so the results are the same.
  • Device: Samsung Galaxy A14 (SM-A145R, Android 15), RNTester built with Gradle in Release (assembleRelease, arm64-v8a) and compiled with cmd package compile -m speed. The scenario is a local Playground screen, not part of this PR: a long feed with avatars and photos from the bundle that scrolls by itself.
  • A/B setup: a single APK with a local switch (an adb shell setprop, not part of this PR) that runs either the old toInt() with try/catch or toIntOrNull(), and times every call. Launches alternate A B B A A B B A, 4 per arm. Every launch made 1,300 lookups.
before this PR change
Time per getResourceDrawableId 239–243 µs 16.4–17.3 µs −93%
  • Perfetto (30 s of the same feed): ReactImageManager.setSource went from 3.5% to 1.6% of the main thread's samples, and the samples in exception handling under it from 237 to 0.
  • Rendering: screenshots of the feed in both arms are byte-identical.

🤖 Generated with Claude Code

ResourceDrawableIdHelper.getResourceDrawableId first tried to parse the
resource name as a number with toInt() and caught the
NumberFormatException. Bundled images in Release builds are drawable
resources whose names are not numbers, so every such image source threw
an exception and filled in its stack trace. Use toIntOrNull() instead,
which parses the same way without throwing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 24, 2026
@facebook-github-tools facebook-github-tools Bot added p: Software Mansion Partner: Software Mansion Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Oct 24, 2026
@github-actions

Copy link
Copy Markdown

Visual regression

No visual differences at 606fafacf8ec.

ios: no capture

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Software Mansion Partner: Software Mansion Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant