Skip to content

feat(android) - url function support in backgroundImage - #58247

Open
intergalacticspacehighway wants to merge 7 commits into
react:mainfrom
intergalacticspacehighway:background-image-url-android
Open

intergalacticspacehighway wants to merge 7 commits into
react:mainfrom
intergalacticspacehighway:background-image-url-android

Conversation

@intergalacticspacehighway

@intergalacticspacehighway intergalacticspacehighway commented Aug 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary:

Recreated from #54994, which was auto-closed when my fork was deleted. GitHub does not allow reopening a PR whose head repository is gone. Rebased onto current main.

How:

Uses Fresco's image pipeline to fetch the image in BackgroundImageURLLoader. Keeps Fresco's CloseableReference open and draws the shared bitmap in the BackgroundImageDrawable canvas using drawBitmap, like Fresco's drawee. Background images with the same url share one bitmap. The reference is released when the url changes or the view is dropped.

Changelog:

[ANDROID] [ADDED] - url support with backgroundImage

Test Plan:

Screenshots

Each url() example in RN Tester, opened by deep link, on the Android emulator, with all three PRs merged:

URL Image URL Image from local file Local file at its natural size (@3x asset, 33x33)

Follow-ups

  • Decode images at the size they are drawn, instead of full size.
  • cover and contain support for backgroundSize.

@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 Aug 30, 2026
@intergalacticspacehighway
intergalacticspacehighway marked this pull request as draft August 30, 2026 13:05
@intergalacticspacehighway
intergalacticspacehighway force-pushed the background-image-url-android branch 3 times, most recently from 5455ef6 to d1c80d3 Compare August 31, 2026 14:52
copy bitmap on background thread
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Visual regression

No visual differences at 6f67f1916d05.

ios: no capture

BackgroundImageURLLoader keeps one entry for each unique uri, keeps the
entries for uris that did not change, redraws after each image, and
ignores callbacks from cancelled entries. All state changes happen on
the UI thread.

The loaded bitmap is copied with its EXIF orientation applied, in the
same way as Fresco's OrientedDrawable. An auto dimension in
backgroundSize keeps the image's aspect ratio for url() layers.
Pending requests are cancelled when the view is detached or hidden,
and started again when it is shown.
- Keep the public BackgroundImageLayer API unchanged. url() data is in
  internal fields, so ReactAndroid.api matches main again.
- Cap the decode at screen size and keep the natural size from the
  encoded image, so large photos do not crash the hardware canvas.
- Show the first frame of animated images, as iOS does.
- Return null for a non-string uri instead of throwing.
- Start requests only while the drawable is visible, and catch up in
  draw() when the view skipped setVisible(true).
- Filter scaled bitmaps, and create the tile rectangles once per layer.
Remove the decode size limit, so background images load like <Image>
network images. Decoding at the drawn size will follow in a separate
change on both platforms.
…roid

- Start the requests when backgroundImage is set, and cancel them in
  ReactViewManager.onDropViewInstance, as iOS does in finalizeUpdates
  and prepareForRecycle. This removes the setVisible and draw() logic.
- Copy the bitmap on a Fresco background thread. A cached image calls
  back at once, so the copy ran on the UI thread.
- background-repeat: round uses at least one tile, as CSS requires.
- Add BackgroundImageLayer parse tests.
Each view copied the decoded bitmap, so N views with the same url held
N full-size copies. Keep Fresco's CloseableReference open instead and
draw the shared bitmap, as Fresco's drawee does. EXIF orientation is
applied with a matrix at draw time. The reference is released through
DeferredReleaser on cancel.

20 views with the same 1800x1200 image: native heap +178 MB before,
+9.3 MB after.
The canvas throws for a bitmap that is too large to draw. Catch the
exception around the tile loop, restore the canvas, and log it, like
ReactImageView does for <Image>.
@intergalacticspacehighway
intergalacticspacehighway marked this pull request as ready for review October 29, 2026 14:35
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 29, 2026

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. 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