Migrated packages/react-native-reanimated java->kotlin#9163
Migrated packages/react-native-reanimated java->kotlin#9163tshmieldev wants to merge 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Migrates the Android implementation of react-native-reanimated from Java to Kotlin, updating core runtime, keyboard, sensors, and native-proxy bridging code while adjusting the Android Gradle setup to compile Kotlin sources.
Changes:
- Replaced multiple Android Java classes (core runtime + keyboard + sensors + JNI bridge helpers) with Kotlin equivalents.
- Updated
NativeProxy/NodesManagerplumbing and supporting utilities (CopiedEvent,DrawPassDetector,DevMenuUtils, etc.) in Kotlin. - Modified
android/build.gradleto apply the Kotlin Android plugin and add Kotlin-related dependencies.
Reviewed changes
Copilot reviewed 49 out of 49 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-reanimated/android/build.gradle | Enables Kotlin compilation and adds Kotlin-related dependencies (currently with duplication/conflicts). |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorType.kt | Kotlin enum replacement for sensor type mapping. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorType.java | Removed Java sensor type enum. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorListener.kt | Kotlin sensor event listener replacement. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorListener.java | Removed Java sensor listener. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorContainer.kt | Kotlin container managing sensor registrations. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorContainer.java | Removed Java sensor container. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensor.kt | Kotlin sensor wrapper handling manager/listener registration. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensor.java | Removed Java sensor wrapper. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/SensorSetter.kt | Kotlin HybridData-backed JNI setter wrapper. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/SensorSetter.java | Removed Java SensorSetter. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/NoopEventHandler.kt | Kotlin no-op RCTEventEmitter implementation. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/NoopEventHandler.java | Removed Java no-op event handler. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/EventHandler.kt | Kotlin event handler bridging to native receiveEvent. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/EventHandler.java | Removed Java event handler. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/AnimationFrameCallback.kt | Kotlin HybridData callback implementing OnAnimationFrame. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nativeProxy/AnimationFrameCallback.java | Removed Java animation frame callback. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.kt | Kotlin window insets observer for keyboard handling. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.java | Removed Java WindowsInsetsManager. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardWorkletWrapper.kt | Kotlin HybridData wrapper for keyboard worklet invocation. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardWorkletWrapper.java | Removed Java keyboard worklet wrapper. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardState.kt | Kotlin enum for keyboard state values. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardState.java | Removed Java KeyboardState. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationManager.kt | Kotlin manager for keyboard event subscriptions and callbacks. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationManager.java | Removed Java keyboard animation manager. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationCallback.kt | Kotlin WindowInsetsAnimationCompat.Callback implementation. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationCallback.java | Removed Java keyboard animation callback. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.kt | Kotlin keyboard state/height tracker. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java | Removed Java keyboard tracker. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/Utils.kt | Kotlin utility functions (processMapping, processIntArray, etc.). |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/Utils.java | Removed Java Utils. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.kt | Kotlin RN package registration for the module. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.java | Removed Java ReanimatedPackage. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedModule.kt | Kotlin native module implementation + lifecycle hooks. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedModule.java | Removed Java ReanimatedModule. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.kt | Kotlin NodesManager handling events, choreographer callbacks, and draw-pass logic. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java | Removed Java NodesManager. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt | Kotlin NativeProxy JNI bridge + UI prop updates, sensors, keyboard APIs. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java | Removed Java NativeProxy. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/MapUtils.kt | Kotlin map access helpers throwing JS exceptions. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/MapUtils.java | Removed Java MapUtils. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/DrawPassDetector.kt | Kotlin draw-pass detection via decor view OnDrawListener. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/DrawPassDetector.java | Removed Java DrawPassDetector. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/DevMenuUtils.kt | Kotlin dev-menu integration helper. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/DevMenuUtils.java | Removed Java DevMenuUtils. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/CopiedEvent.kt | Kotlin event snapshotting for cross-thread dispatch. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/CopiedEvent.java | Removed Java CopiedEvent. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/common/GestureHandlerStateManager.kt | Kotlin interface for gesture handler state updates. |
| packages/react-native-reanimated/android/src/main/java/com/swmansion/common/GestureHandlerStateManager.java | Removed Java GestureHandlerStateManager. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| kotlinOptions { | ||
| jvmTarget = '17' | ||
| } | ||
| if (project != rootProject) { | ||
| kotlinOptions { | ||
| jvmTarget = '17' | ||
| } | ||
| } |
There was a problem hiding this comment.
kotlinOptions { jvmTarget = '17' } is configured twice (once unconditionally and once under if (project != rootProject)). This duplication is easy to drift and makes it unclear which block is authoritative. Prefer a single kotlinOptions configuration (or keep it only in the conditional block, matching the worklets module).
| implementation "androidx.core:core:1.15.0" | ||
|
|
||
| implementation "com.facebook.react:react-android" // version substituted by RNGP | ||
| implementation "androidx.core:core-ktx:1.17.0" |
There was a problem hiding this comment.
There are two androidx.core:core-ktx dependencies declared with different versions. This can lead to unpredictable dependency resolution and larger/duplicated classes on the classpath. Keep a single core-ktx dependency and align its version with the rest of the repo (e.g., the worklets Android module).
| implementation "androidx.core:core-ktx:1.17.0" |
| init { | ||
| val wm = reactContext.get()!!.getSystemService(Context.WINDOW_SERVICE) as WindowManager | ||
| val display = wm.defaultDisplay | ||
| listener = ReanimatedSensorListener(setter, interval.toDouble(), display) | ||
| sensorManager = | ||
| reactContext.get()!!.getSystemService(Context.SENSOR_SERVICE) as SensorManager | ||
| this.interval = if (interval == -1) DEFAULT_INTERVAL else interval | ||
| } |
There was a problem hiding this comment.
ReanimatedSensorListener is constructed with the raw interval argument before the -1 ("auto") value is mapped to DEFAULT_INTERVAL. For interval == -1, the listener’s throttling check effectively disables throttling (current - lastRead < -1 is never true). Compute the effective interval first (defaulting when -1) and pass that value to both the listener and registerListener.
There was a problem hiding this comment.
We can verify this comment in the following PR as this is the exact behavior as previously.
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt
Outdated
Show resolved
Hide resolved
| import com.facebook.react.module.annotations.ReactModule | ||
| import com.facebook.react.module.model.ReactModuleInfo | ||
| import com.facebook.react.module.model.ReactModuleInfoProvider | ||
| import java.util.HashMap | ||
| import java.util.Objects | ||
|
|
There was a problem hiding this comment.
ReanimatedPackage previously had a @ReactModuleList annotation (and react-native-worklets still uses it). Dropping this annotation may affect React Native module list/codegen tooling depending on the build setup. Either re-add @ReactModuleList(nativeModules = [ReanimatedModule::class]) or confirm it’s intentionally removed and safe for all supported RN versions.
| import com.facebook.react.module.annotations.ReactModule | |
| import com.facebook.react.module.model.ReactModuleInfo | |
| import com.facebook.react.module.model.ReactModuleInfoProvider | |
| import java.util.HashMap | |
| import java.util.Objects | |
| import com.facebook.react.module.annotations.ReactModule | |
| import com.facebook.react.module.annotations.ReactModuleList | |
| import com.facebook.react.module.model.ReactModuleInfo | |
| import com.facebook.react.module.model.ReactModuleInfoProvider | |
| import java.util.HashMap | |
| import java.util.Objects | |
| @ReactModuleList(nativeModules = [ReanimatedModule::class]) |
| apply plugin: "com.android.library" | ||
| apply plugin: "maven-publish" | ||
| apply plugin: "de.undercouch.download" | ||
| apply plugin: 'org.jetbrains.kotlin.android' | ||
|
|
||
| if (project != rootProject) { | ||
| apply plugin: "org.jetbrains.kotlin.android" | ||
| } |
There was a problem hiding this comment.
org.jetbrains.kotlin.android is applied unconditionally and then applied again for non-root projects. This differs from the pattern used in react-native-worklets (only applied when project != rootProject) and can cause redundant plugin application / configuration warnings. Consider applying the Kotlin Android plugin only once (likely inside the project != rootProject branch).
Co-authored-by: Copilot <[email protected]>
tjzel
left a comment
There was a problem hiding this comment.
I have the same remarks as Copilot, please address them
|
Also CI is failing due to the issues in |
Summary
Migrated packages/react-native-reanimated java->kotlin
Test plan
Successfully built and tested the fabric-example app