Skip to content

Commit 3a95e0e

Browse files
hannojgmeta-codesync[bot]
authored andcommitted
fix(android): Image defaultSource & loadingIndicatorSrc broken with props 2.0 (#55210)
Summary: Fixes crashes using <Image> component on android with props 2.0 enabled using feature flag: ``` enablePropsUpdateReconciliationAndroid ``` <details> <summary>Crash stack</summary> ``` Error while updating prop source java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Caused by: com.facebook.react.bridge.NoSuchKeyException: width at com.facebook.react.bridge.ReadableNativeMap.getValue(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:3) at com.facebook.react.bridge.ReadableNativeMap.getDouble(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at r2.l.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:143) at com.facebook.react.views.image.ReactImageManager.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Exception thrown when executing UIFrameGuarded com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'source' of a view managed by: RCTImageView at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:144) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Caused by: com.facebook.react.bridge.NoSuchKeyException: width at com.facebook.react.bridge.ReadableNativeMap.getValue(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:3) at com.facebook.react.bridge.ReadableNativeMap.getDouble(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at r2.l.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:143) at com.facebook.react.views.image.ReactImageManager.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) ReactHost{0}.handleHostException(message = "Error while updating property 'source' of a view managed by: RCTImageView") Shutting down VM FATAL EXCEPTION: main Process: com.facebook.react.uiapp, PID: 23676 com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'source' of a view managed by: RCTImageView at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:144) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) Caused by: com.facebook.react.bridge.NoSuchKeyException: width at com.facebook.react.bridge.ReadableNativeMap.getValue(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:3) at com.facebook.react.bridge.ReadableNativeMap.getDouble(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at r2.l.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:143) at com.facebook.react.views.image.ReactImageManager.setSource(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:6) at java.lang.reflect.Method.invoke(Native Method) at G0.a.q(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:89) at com.facebook.react.uimanager.ViewManager.updateProperties(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:33) at com.facebook.react.uimanager.ViewManager.createViewInstance(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:12) at com.facebook.react.uimanager.ViewManager.createView(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at q1.h.b(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:62) at r1.g.execute(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:67) at q1.b.d(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:71) at q1.b.c(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:64) at m1.j.a(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:100) at com.facebook.react.uimanager.d.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:1) at E1.o.doFrame(r8-map-id-1a92cc952529f7daea85f71c4ad30656f52b60c3e338ced74ff1293d461ae7b1:98) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2457) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doAnimationLoad(Choreographer.java:1523) at android.view.Choreographer.doFrame(Choreographer.java:1438) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9911) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957) ``` </details> On android we pass the `defaultSource` and `loadingIndicatorSrc` as strings. however, when enabling prop diffing this causes crashes, as the prop diff mechanism is parsing them to `ImageSource` as defined in `ImageProps.h`. W/o props 2.0 diffing we simply return the props as we receive them from JS (with those sources as string): https://github.com/facebook/react-native/blob/c12806c4937ea76d65e89e6f0857e4c96e47c927/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp#L341 With props diffing … https://github.com/facebook/react-native/blob/c12806c4937ea76d65e89e6f0857e4c96e47c927/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp#L309 … We actually transform them to the c++ object: https://github.com/facebook/react-native/blob/c12806c4937ea76d65e89e6f0857e4c96e47c927/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp#L210-L215 https://github.com/facebook/react-native/blob/c12806c4937ea76d65e89e6f0857e4c96e47c927/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h#L29-L30 https://github.com/facebook/react-native/blob/c12806c4937ea76d65e89e6f0857e4c96e47c927/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h#L47-L74 This throws errors and crashes the app: https://github.com/user-attachments/assets/04d20369-f49a-4170-8747-643766fba971 I think the proper solution here is to pass the full objects down, with or without props 2.0 diffing and handle the objects in native code correctly. This way android aligns with the iOS implementation too. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [Android][Fixed] - Fix `<Image>` crash with `defaultSource` and `loadingIndicatorSource` when `enablePropsUpdateReconciliationAndroid` is enabled [Android][Added] - Add `Dynamic` overloads of `ReactImageManager#setDefaultSource` and `ReactImageManager#setLoadingIndicatorSource` that accept either a uri string or an image source object [Android][Deprecated] - Deprecate the `String?` overloads of `ReactImageManager#setDefaultSource` and `ReactImageManager#setLoadingIndicatorSource` Pull Request resolved: #55210 Test Plan: 1. Test that the defaultProp example in RNTester is working 2. Enable props 2.0 diffing mechanism: ```diff diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt index bb0a6b5..04fcbf4ba8f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt @@ -11,4 +11,8 @@ public class ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android() : ReactNativeNewArchitectureFeatureFlagsDefaults() { override fun useFabricInterop(): Boolean = true + + override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = true + override fun enablePropsUpdateReconciliationAndroid(): Boolean = true + override fun enableExclusivePropsUpdateAndroid(): Boolean = true } ``` 3. Test all image examples: - Verify there is no crash - Verify defaultSource example is working Recordings: | Debug | Release | |--------|--------| | <video src="https://github.com/user-attachments/assets/df5d75e7-4666-4201-81e7-39271c54fe0b" /> | <video src="https://github.com/user-attachments/assets/d64fcefd-6d1f-4d84-8581-363ff572a721" /> | Note: this uses the example setup from this PR in the recordings: - #55234 Reviewed By: cortinico Differential Revision: D112105149 Pulled By: coado fbshipit-source-id: 966afaeedee93b88a7767e6f46d1521a02902dd0
1 parent 917d97e commit 3a95e0e

3 files changed

Lines changed: 39 additions & 3 deletions

File tree

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5313,11 +5313,13 @@ public final class com/facebook/react/views/image/ReactImageManager : com/facebo
53135313
public final fun setBorderColor (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/Integer;)V
53145314
public final fun setBorderRadius (Lcom/facebook/react/views/image/ReactImageView;IF)V
53155315
public final fun setBorderWidth (Lcom/facebook/react/views/image/ReactImageView;F)V
5316+
public final fun setDefaultSource (Lcom/facebook/react/views/image/ReactImageView;Lcom/facebook/react/bridge/Dynamic;)V
53165317
public final fun setDefaultSource (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/String;)V
53175318
public final fun setFadeDuration (Lcom/facebook/react/views/image/ReactImageView;I)V
53185319
public final fun setHeaders (Lcom/facebook/react/views/image/ReactImageView;Lcom/facebook/react/bridge/ReadableMap;)V
53195320
public final fun setInternal_AnalyticsTag (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/String;)V
53205321
public final fun setLoadHandlersRegistered (Lcom/facebook/react/views/image/ReactImageView;Z)V
5322+
public final fun setLoadingIndicatorSource (Lcom/facebook/react/views/image/ReactImageView;Lcom/facebook/react/bridge/Dynamic;)V
53215323
public final fun setLoadingIndicatorSource (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/String;)V
53225324
public final fun setOverlayColor (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/Integer;)V
53235325
public final fun setProgressiveRenderingEnabled (Lcom/facebook/react/views/image/ReactImageView;Z)V

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import android.graphics.PorterDuff
1212
import com.facebook.common.logging.FLog
1313
import com.facebook.drawee.backends.pipeline.Fresco
1414
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder
15+
import com.facebook.react.bridge.Dynamic
1516
import com.facebook.react.bridge.ReadableArray
1617
import com.facebook.react.bridge.ReadableMap
18+
import com.facebook.react.bridge.ReadableType
1719
import com.facebook.react.common.ReactConstants
1820
import com.facebook.react.module.annotations.ReactModule
1921
import com.facebook.react.uimanager.BackgroundStyleApplicator
@@ -133,16 +135,44 @@ public constructor(
133135
}
134136

135137
@ReactProp(name = "defaultSource")
138+
public fun setDefaultSource(view: ReactImageView, source: Dynamic) {
139+
view.setDefaultSource(imageSourceUri(source))
140+
}
141+
142+
@Deprecated(
143+
"Retained only for binary/source compatibility; the defaultSource prop is now delivered " +
144+
"through the Dynamic overload."
145+
)
136146
public fun setDefaultSource(view: ReactImageView, source: String?) {
137147
view.setDefaultSource(source)
138148
}
139149

140150
// In JS this is Image.props.loadingIndicatorSource.uri
141151
@ReactProp(name = "loadingIndicatorSrc")
152+
public fun setLoadingIndicatorSource(view: ReactImageView, source: Dynamic) {
153+
view.setLoadingIndicatorSource(imageSourceUri(source))
154+
}
155+
156+
@Deprecated(
157+
"Retained only for binary/source compatibility; the loadingIndicatorSrc prop is now " +
158+
"delivered through the Dynamic overload."
159+
)
142160
public fun setLoadingIndicatorSource(view: ReactImageView, source: String?) {
143161
view.setLoadingIndicatorSource(source)
144162
}
145163

164+
/**
165+
* The legacy raw-props path delivers these props as a plain uri string, but the Props 2.0 diffing
166+
* path (`ImageProps::getDiffProps`) serializes the full ImageSource object. Accept both formats
167+
* so either pipeline (and either side of a JS/native version skew) keeps working.
168+
*/
169+
private fun imageSourceUri(source: Dynamic): String? =
170+
when (source.type) {
171+
ReadableType.String -> source.asString()
172+
ReadableType.Map -> source.asMap()?.getString("uri")
173+
else -> null
174+
}
175+
146176
@ReactProp(name = "borderColor", customType = "Color")
147177
public fun setBorderColor(view: ReactImageView, borderColor: Int?) {
148178
BackgroundStyleApplicator.setBorderColor(view, LogicalEdge.ALL, borderColor)

packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,14 @@ ImageProps::ImageProps(
2727
"defaultSource",
2828
sourceProps.defaultSource,
2929
{})),
30+
// The wire name of this prop is "loadingIndicatorSrc"
31+
// (ImageViewNativeComponent.js / the Android @ReactProp setter);
32+
// "loadingIndicatorSource" is only the JS-facing <Image> prop that
33+
// Image.android.js translates.
3034
loadingIndicatorSource(convertRawProp(
3135
context,
3236
rawProps,
33-
"loadingIndicatorSource",
37+
"loadingIndicatorSrc",
3438
sourceProps.loadingIndicatorSource,
3539
{})),
3640
resizeMode(convertRawProp(
@@ -115,7 +119,7 @@ void ImageProps::setProp(
115119
switch (hash) {
116120
RAW_SET_PROP_SWITCH_CASE(sources, "source");
117121
RAW_SET_PROP_SWITCH_CASE(defaultSource, "defaultSource");
118-
RAW_SET_PROP_SWITCH_CASE(loadingIndicatorSource, "loadingIndicatorSource");
122+
RAW_SET_PROP_SWITCH_CASE(loadingIndicatorSource, "loadingIndicatorSrc");
119123
RAW_SET_PROP_SWITCH_CASE_BASIC(resizeMode);
120124
RAW_SET_PROP_SWITCH_CASE_BASIC(blurRadius);
121125
RAW_SET_PROP_SWITCH_CASE_BASIC(capInsets);
@@ -167,7 +171,7 @@ folly::dynamic ImageProps::getDiffProps(const Props* prevProps) const {
167171
}
168172

169173
if (loadingIndicatorSource != oldProps->loadingIndicatorSource) {
170-
result["loadingIndicatorSource"] = toDynamic(loadingIndicatorSource);
174+
result["loadingIndicatorSrc"] = toDynamic(loadingIndicatorSource);
171175
}
172176

173177
if (resizeMode != oldProps->resizeMode) {

0 commit comments

Comments
 (0)