Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android events don't get fired using mEventDispatcher.dispatchEvent with the New Architecture and bridgeless off #43635

Closed
gabrieldonadel opened this issue Mar 24, 2024 · 4 comments
Labels
p: Expo Partner: Expo Partner Platform: Android Android applications. Resolution: Answered When the issue is resolved with a simple answer Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)

Comments

@gabrieldonadel
Copy link
Contributor

Description

While migrating some libraries to be compatible with the new architecture I notice this problem where on Android, events don't get fired when using mEventDispatcher.dispatchEvent with the New Architecture and bridgeless off, but these same events work fine when running using the old arch or with bridgeless on.

It seems that for some reason this.mFabricEventEmitter from ReactEventEmitter is null when an event is fired

Steps to reproduce

  1. Using a non migrated custom view module, fire an event from the native side using mEventDispatcher.dispatchEvent()
  2. Observe that the event is not received on the JS side

React Native Version

0.74.0-rc.4

Affected Platforms

Runtime - Android

Areas

Fabric - The New Renderer, Bridgeless - The New Initialization Flow

Output of npx react-native info

System:
  OS: macOS 14.0
  CPU: (12) arm64 Apple M2 Max
  Memory: 114.81 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.11.1
    path: ~/.volta/tools/image/node/20.11.1/bin/node
  Yarn:
    version: 3.6.4
    path: ~/.volta/tools/image/yarn/1.22.22/bin/yarn
  npm:
    version: 10.2.4
    path: ~/.volta/tools/image/node/20.11.1/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.14.3
    path: /Users/gabriel/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.2
      - iOS 17.2
      - macOS 14.2
      - tvOS 17.2
      - visionOS 1.0
      - watchOS 10.2
  Android SDK:
    API Levels:
      - "22"
      - "26"
      - "30"
      - "31"
      - "33"
      - "34"
    Build Tools:
      - 26.0.3
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 33.0.2
      - 34.0.0
    System Images:
      - android-22 | ARM 64 v8a
      - android-26 | Google APIs Intel x86_64 Atom
      - android-30 | ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
      - android-33 | Google Play ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2023.2 AI-232.10300.40.2321.11567975
  Xcode:
    version: 15.2/15C500b
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.8
    path: /usr/bin/javac
  Ruby:
    version: 2.7.8
    path: /Users/gabriel/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.0-rc.4
    wanted: 0.74.0-rc.4
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: true

Stacktrace or Logs

Unhandled SoftException
                                                                                                    com.facebook.react.bridge.ReactNoCrashSoftException: Cannot find EventEmitter for receiveEvent: SurfaceId[1] ReactTag[16] UIManagerType[2] EventName[topChange]
                                                                                                    	at com.facebook.react.uimanager.events.ReactEventEmitter.receiveEvent(ReactEventEmitter.java:148)
                                                                                                    	at com.facebook.react.uimanager.events.Event.dispatchModern(Event.java:189)
                                                                                                    	at com.facebook.react.uimanager.events.EventDispatcherImpl$DispatchEventsRunnable.run(EventDispatcherImpl.java:376)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:942)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:201)
                                                                                                    	at android.os.Looper.loop(Looper.java:288)
                                                                                                    	at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
                                                                                                    	at java.lang.Thread.run(Thread.java:1012)

Reproducer

https://github.com/gabrieldonadel/react-native-android-event-dispatcher-bug

Screenshots and Videos

old arch new arch
with bridge bridgeless
Screen.Recording.2024-03-23.at.15.18.39.mov
Screen.Recording.2024-03-23.at.15.12.34.mov
Screen.Recording.2024-03-23.at.15.17.26.mov
@gabrieldonadel gabrieldonadel added Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules) labels Mar 24, 2024
@github-actions github-actions bot added the Platform: Android Android applications. label Mar 24, 2024
@cortinico
Copy link
Contributor

@gabrieldonadel Thanks for the reproducer it was extremely valuable for me to isolate the issue. A fix is forthcoming

cortinico added a commit to cortinico/react-native that referenced this issue Mar 25, 2024
Summary:
When on bridge-mode, users are reporting that events are not dispatched well on Android.
This is happening because `ReactEventEmitter` is checking wether the view is on Fabric or Paper,
and dispatching the event properly.

When on Bridge mode, on a Paper legacy view, the `uiManagerType` would be `UIManagerType.FABRIC` (as the RootView is set with Fabric Enabled),
but the `mFabricEventEmitter` will be null. So this results on events being completely ignored.

I've fixed this by checking if the user has enabled Fabric Interop mode, and if so, use the default event emitter.
Fixes facebook#43635

Changelog:
[Android] [Fixed] - Fix ReactEventEmitter on bridge-mode

Differential Revision: D55317418
cortinico added a commit to cortinico/react-native that referenced this issue Mar 25, 2024
Summary:

When on bridge-mode, users are reporting that events are not dispatched well on Android.
This is happening because `ReactEventEmitter` is checking wether the view is on Fabric or Paper,
and dispatching the event properly.

When on Bridge mode, on a Paper legacy view, the `uiManagerType` would be `UIManagerType.FABRIC` (as the RootView is set with Fabric Enabled),
but the `mFabricEventEmitter` will be null. So this results on events being completely ignored.

I've fixed this by checking if the user has enabled Fabric Interop mode, and if so, use the default event emitter.
Fixes facebook#43635

Changelog:
[Android] [Fixed] - Fix ReactEventEmitter on bridge-mode

Differential Revision: D55317418
@javache
Copy link
Member

javache commented Mar 25, 2024

Noticed that in your sample, your accessing the event emitter here.

mEventDispatcher = UIManagerHelper.getEventDispatcherForReactTag((ReactContext) getContext(), getId());

I don't believe this is safe, as at this point RN will not have initialized the Id field yet, and we'll fall back to the paper event dispatcher even if this is a Fabric view.

@gabrieldonadel
Copy link
Contributor Author

Noticed that in your sample, your accessing the event emitter here.

mEventDispatcher = UIManagerHelper.getEventDispatcherForReactTag((ReactContext) getContext(), getId());

I don't believe this is safe, as at this point RN will not have initialized the Id field yet, and we'll fall back to the paper event dispatcher even if this is a Fabric view.

I see, thanks for the explanation. If the UIManagerHelper.getEventDispatcherForReactTag call were to only occur inside the action event (e.g. onClick) this would be fine, right?

@cortinico
Copy link
Contributor

I see, thanks for the explanation. If the UIManagerHelper.getEventDispatcherForReactTag call were to only occur inside the action event (e.g. onClick) this would be fine, right?

Yup I've tested this in your repro and it effectively fixes the issue 👍

@cortinico cortinico added Resolution: Answered When the issue is resolved with a simple answer and removed Needs: Triage 🔍 labels Mar 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p: Expo Partner: Expo Partner Platform: Android Android applications. Resolution: Answered When the issue is resolved with a simple answer Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants