From 9f65442f2d1c52afd987b9971fe04a8c7b3e032f Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 8 Nov 2024 11:07:26 -0800 Subject: [PATCH] Fix timers in headless tasks on bridgeless mode (#47496) Summary: Fixes https://github.com/facebook/react-native/issues/47495 `JavaTimerManager` is being registered to receive headless tasks events in the [`TimingModule`](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt#L28-L29). This module is not used on bridgeless: [1](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/Libraries/Core/setUpTimers.js#L44-L61), [2](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/Libraries/Core/setUpTimers.js#L123-L132) and since it's loaded lazily, the event listener is never registered. This PR moves registration to the constructor of `JavaTimerManager` and deregistration to the `onInstanceDestroy` method. This way the event listener is always registered when an instance of the timer manager exists. ## Changelog: [ANDROID] [FIXED] - Fix timers in headless tasks on bridgeless mode Pull Request resolved: https://github.com/facebook/react-native/pull/47496 Test Plan: See the reproducer from the issue Reviewed By: javache Differential Revision: D65615601 Pulled By: alanleedev fbshipit-source-id: 6e1d36f8783e813065f79730a928b99c3e385718 --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 1 - .../com/facebook/react/modules/core/JavaTimerManager.kt | 2 ++ .../java/com/facebook/react/modules/core/TimingModule.kt | 8 -------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 12cd26ec4bad92..72e4d9f4da80ab 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3306,7 +3306,6 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f public fun createTimer (DDDZ)V public fun deleteTimer (D)V public fun emitTimeDriftWarning (Ljava/lang/String;)V - public fun initialize ()V public fun invalidate ()V public fun setSendIdleEvents (Z)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt index ecce67478dd9d0..8b6571698fc5dd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt @@ -65,6 +65,7 @@ public open class JavaTimerManager( init { reactApplicationContext.addLifecycleEventListener(this) + HeadlessJsTaskContext.getInstance(reactApplicationContext).addTaskEventListener(this) } override fun onHostPause() { @@ -103,6 +104,7 @@ public open class JavaTimerManager( } public open fun onInstanceDestroy() { + HeadlessJsTaskContext.getInstance(reactApplicationContext).removeTaskEventListener(this) reactApplicationContext.removeLifecycleEventListener(this) clearFrameCallback() clearChoreographerIdleCallback() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt index bfa0219acf2454..caf7846a322d86 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt @@ -12,7 +12,6 @@ import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.WritableArray import com.facebook.react.common.annotations.VisibleForTesting import com.facebook.react.devsupport.interfaces.DevSupportManager -import com.facebook.react.jstasks.HeadlessJsTaskContext import com.facebook.react.module.annotations.ReactModule /** Native module for JS timer execution. Timers fire on frame boundaries. */ @@ -24,11 +23,6 @@ public class TimingModule( private val javaTimerManager: JavaTimerManager = JavaTimerManager(reactContext, this, ReactChoreographer.getInstance(), devSupportManager) - override fun initialize() { - HeadlessJsTaskContext.getInstance(getReactApplicationContext()) - .addTaskEventListener(javaTimerManager) - } - override fun createTimer( callbackIDDouble: Double, durationDouble: Double, @@ -68,8 +62,6 @@ public class TimingModule( } override fun invalidate() { - val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext()) - headlessJsTaskContext.removeTaskEventListener(javaTimerManager) javaTimerManager.onInstanceDestroy() }