Repository navigation
fix(android): stop Fresco "Don't know how to round that drawable" warnings on images - #58855
Open
franruiztech wants to merge 1 commit into
Open
franruiztech wants to merge 1 commit into
franruiztech wants to merge 1 commit into
Conversation
…nings on images ReactImageDownloadListener doubles as the progress bar drawable of the image hierarchy, wrapping a private EmptyDrawable. ReactImageView builds its hierarchy with RoundingParams, and Fresco applies those to the leaf of every child drawable (WrappingUtils.maybeApplyLeafRounding). It only knows how to round bitmap, nine-patch and color drawables, so for any other leaf it logs "Don't know how to round that drawable" at warn level, once for the progress bar plus once per later update. Wrap a transparent ColorDrawable instead, which Fresco can round and which still renders nothing. ReactImageView also called setProgressBarImage with the same listener on every update. After the first call the leaf is already a RoundedColorDrawable, which is not a ColorDrawable, so Fresco would warn again. Install the progress bar only when the listener changes.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
When an
<Image>hasonProgress,onLoadStart,onLoadoronLoadEndhandlers,ReactImageViewcreates aReactImageDownloadListener. This class doubles as the progress bar drawable of the Drawee hierarchy: it is aForwardingDrawablewrapping a privateEmptyDrawable.ReactImageViewbuilds its hierarchy withRoundingParams, and Fresco applies the rounding to the leaf of every child drawable (WrappingUtils.maybeApplyLeafRounding). It can only round bitmap, nine-patch and color drawables, so forEmptyDrawableit logsDon't know how to round that drawableat warn level (tagunknown:WrappingUtils).maybeUpdateViewFromRequestcallshierarchy.setProgressBarImage(downloadListener)on every update, and the hierarchy also re-applies rounding when the rounding params are set, so the line is printed repeatedly (173 times in a typical session on 0.85.3). Fresco reports the same thing for custom progress drawables in facebook/fresco#2369.Two changes:
ReactImageDownloadListenerwrapsColorDrawable(Color.TRANSPARENT)instead ofEmptyDrawable. Fresco can round it, and it still draws nothing.EmptyDrawableis removed.ReactImageViewinstalls the progress bar image once per listener instead of on every update. This is needed as well: after the first call the leaf has become aRoundedColorDrawable, which is not aColorDrawable, so Fresco would warn again on the nextsetProgressBarImagewith the same listener. Setting an already installed drawable again has no other effect.One behavior difference remains. Once Fresco rounds the leaf, the leaf is a transparent
RoundedColorDrawableinstead of the unroundedEmptyDrawable, sogetOpacity()of the composite Drawee drawable goes fromOPAQUEtoTRANSPARENTfor opaque images that have load handlers. As a resultImageView.isOpaque()goes fromtruetofalsefor those views. Nothing is painted differently: the progress bar draws nothing either way, and the rest of the hierarchy is unchanged. Only code that reads the opacity (for example to skip drawing what is behind the view) sees the difference.buildHierarchyand itsRoundingParams.fromCornersRadius(0f)are left as they are.Changelog:
[ANDROID] [FIXED] - Stop Fresco from logging "Don't know how to round that drawable" for images with load/progress events
Test Plan:
Added
testProgressBarImageDoesNotWarnAboutRoundingtoReactImagePropertyTest: it creates aReactImageView, enables load events, runsmaybeUpdateViewtwice with different sources, and checks thatFLog.wis never called with Fresco's rounding message.Ran it with
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.views.image.ReactImagePropertyTest: 11 tests, all pass. I also put each half of the change back on its own and ran the same class again; each time only the new test fails, withNeverWantedButInvokedonFLog.w(String, "Don't know how to round that drawable: %s", Object)raised fromWrappingUtils.applyLeafRounding:EmptyDrawableback as the leaf, install-once kept: fails (the warning namesReactImageDownloadListener$EmptyDrawable).ColorDrawableleaf kept,setProgressBarImageon every update: fails (the warning namesRoundedColorDrawable).So both halves are needed and each one is covered by the test. Separately, I compiled the changed classes against the 0.85.3
react-androidrelease AAR and replaced them in it;javap -pshows the public and internal API ofReactImageViewandReactImageDownloadListeneris unchanged apart from the new private field and the removed privateEmptyDrawable.On an Android 9 (API 28) x86_64 emulator, with a release build of an app on 0.85.3 (R8, Hermes, New Architecture), I ran the same scripted flow twice: login, five tabs, a list with about 20 remote logos, a company detail screen, and a cold restart. I counted the matching logcat lines.
react-androidDon't know how to round that drawableStock 0.85.3 on API 26, 31, 33 and 36 gives 227 lines for the same flow. The patched build was run on API 28 and API 34 (Android 14), with 0 lines on both. It did not crash, the logos render with their rounded corners (checked on a screenshot), and the company detail screen works.
Not measured: the
onLoadandonProgressevents beyond the images being painted, and any API level other than 28 for the patched build.The patched
react-androidwas built by recompiling the changed classes and replacing them in the official 0.85.3 AAR, not with a full Gradle build ofReactAndroid.