Skip to content

fix(android): allow GC suspension and attach disposal dispatchers to JNI - #354

Open
wildseansy wants to merge 1 commit into
margelo:mainfrom
PocketConservatory:codex/android-jni-lifecycle
Open

wildseansy wants to merge 1 commit into
margelo:mainfrom
PocketConservatory:codex/android-jni-lifecycle

Conversation

@wildseansy

@wildseansy wildseansy commented Oct 13, 2026 •

Copy link
Copy Markdown

Fixes #351.

Repeated scene replacement on an Android 16 arm64 emulator produced HeapTaskDaemon / SuspendAll timeout aborts while the renderer waited in native code. FilamentChoreographer.onFrame is potentially blocking, so using ordinary JNI instead of @FastNative lets ART suspend the thread for GC.

Resource disposal can also be scheduled from Hermes GC threads. JDispatcher::scheduleTrigger() now uses fbjni ThreadScope::WithClassLoader around both the Java method lookup and invocation, attaching an otherwise unattached caller for that scope.

No JS API changes.

Validation

  • Complete contributor command yarn check-all passes with Yarn Classic 1.22.22 and clang-format 16, using dependencies installed from the frozen upstream Bun lockfile. Separate full yarn lint and yarn typescript also pass; no source formatting changes were required.
  • The same two-file implementation compiled in a React Native 0.81.5 Android arm64 debug consumer.
  • A bounded Android 16 emulator run completed five consecutive model changes/scene recreations without a crash during the observed seven-minute run. This is not exhaustive stress or physical-device validation.
  • Clang-format 16 and git diff --check pass for the changed C++ file/diff.

Fresh upstream Android example validation

A temporary QA checkout based on upstream 0bcf507 combined the three independent PR changes (#354, #355, #356). The unmodified AppExampleFabric app (React Native 0.83.1) built for Android arm64 in 3m26s. Its native engine/Bullet binaries came from the verified upstream 1.11.0 package; tracked engine headers matched byte for byte. This is a combined integration build, not three separate example APK builds.

On an Android 16 arm64 emulator, Home → CameraPan → Home → AnimationTransitions → Home rendered both native models. The process remained alive and its crash buffer was empty during this bounded run. Initial blank startup resolved after restarting with Metro ready, without source changes.

The example's built-in HybridObject smoke test still reports an invalid-enum error when reading the initial enum in unchanged upstream test code (RNFTestHybridObject leaves that field uninitialized). StrictMode warnings also remain. This result establishes bounded rendering/navigation, not a clean pass of every runtime test, the newly documented material-lifetime cases, or physical-device/iOS validation.

Upstream CI

This PR is open for review. At head 423556686d9314dc1ce5389cdc2a7fa715944394, the Build Android and Validate C++ workflows report action_required and need repository-maintainer approval. The local checks recorded above do not establish an upstream CI pass.

@wildseansy

Copy link
Copy Markdown
Author

🍋 Code Reviewer / QA: LGTM at 4235566; no blockers found. JNI attachment and GC-suspension changes are scoped correctly. Validation accurately distinguishes prior downstream smoke testing from the unrun upstream example; CI still needs maintainer approval.

@wildseansy

Copy link
Copy Markdown
Author

🍋 Code Reviewer / QA: Follow-up: a temporary branch combining #354–356 built upstream AppExampleFabric (RN 0.83.1, Android arm64 debug) successfully. On an Android 16 emulator, CameraPan and AnimationTransitions rendered and returned to Home without an observed app crash. This was a bounded smoke check using release prebuilt engine libraries, not exhaustive GC stress; the example's existing HybridObject self-test error and StrictMode warnings remain separate limitations.

@wildseansy

Copy link
Copy Markdown
Author

🥭 Tech Lead: This PR is now open for review at 4235566. The two-file Android fix remains independent of the worklets migration in #349; that PR overlaps the JNI attachment change.

Could a repository maintainer approve the pending Build Android and Validate C++ workflow runs? Both currently report action_required.

The description now reflects the review status and links these runs. Its existing local-build and bounded emulator results remain the validation evidence; no new runtime test or upstream CI pass is claimed.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android scene disposal: GC suspension timeout and unattached JNI callers

1 participant