Skip to content

Android bridgeless: all view events fail — getJSModule(RCTEventEmitter) throws on BridgelessReactContext #437

Description

@Vallabha-Praneeth

Description

Under bridgeless New Architecture on Android, every event RiveReactNativeView emits throws, because the view emits through the legacy RCTEventEmitter JS module and BridgelessReactContext.getJSModule does not support it.

The practical effect is that onLoop, onStateChanged, onPlay, onStop and onRiveEventReceived never reach JS, with no error surfaced on the JS side — the callback simply never fires. For a looping animation it also produces continuous logcat spam, roughly one stack trace per loop.

Stack trace

E unknown:BridgelessReactContext:
  at com.facebook.react.runtime.BridgelessReactContext.getJSModule(BridgelessReactContext.kt:133)
  at com.facebook.react.uimanager.ThemedReactContext.getJSModule(ThemedReactContext.kt:74)
  at com.rivereactnative.RiveReactNativeView.onLoopEnd(RiveReactNativeView.kt:255)
  at com.rivereactnative.RiveReactNativeView$1.notifyLoop(RiveReactNativeView.kt:128)
  at app.rive.runtime.kotlin.controllers.RiveFileController.notifyLoop(RiveFileController.kt:1022)
  at app.rive.runtime.kotlin.renderers.RiveArtboardRenderer.advance(RiveArtboardRenderer.kt:74)

Cause

RiveReactNativeView.kt dispatches events via reactContext.getJSModule(RCTEventEmitter::class.java). I count nine such call sites in the current release (9.8.5) — lines 222, 233, 244, 255, 265, 304, 493 and 1118, plus the import at line 33:

// android/src/main/java/com/rivereactnative/RiveReactNativeView.kt
33:  import com.facebook.react.uimanager.events.RCTEventEmitter
248: fun onLoopEnd(animationName: String, loopMode: RNLoopMode) {
255:   reactContext.getJSModule(RCTEventEmitter::class.java)

getJSModule throws unconditionally on a BridgelessReactContext, so every one of these paths is dead when newArchEnabled=true.

The usual migration is UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewTag) with an Event subclass, which works under both the bridge and bridgeless.

Versions

  • rive-react-native: 9.8.1, and verified unchanged in 9.8.5 (latest at time of writing) by inspecting the published tarball
  • react-native: 0.81.5
  • Expo SDK 55
  • android/gradle.properties: newArchEnabled=true
  • Reproduced on a release build; a debug build surfaces it differently

Note on #190

#190 is closed and looks related, but it is a different symptom — the "'RiveReactNativeView' is not Fabric compatible yet" banner on RN 0.72 / rive 4.1.2. Rendering works fine here; it is specifically the event dispatch that fails. I could not find an existing issue covering this, but apologies if I have missed one.

Workaround for anyone hitting this

Rendering and autoplay are unaffected, so if you only use Rive decoratively you will see log spam and nothing else. If you depend on a completion callback, drive it from a timer instead and make the handler idempotent, since the native callback may never arrive:

const doneOnce = React.useRef(false);
const handleComplete = React.useCallback(() => {
  if (doneOnce.current) return;
  doneOnce.current = true;
  onComplete();
}, [onComplete]);

// Load-bearing under bridgeless: onStateChanged never fires.
React.useEffect(() => {
  const id = setTimeout(handleComplete, ANIMATION_MS);
  return () => clearTimeout(id);
}, [handleComplete]);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions