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
This commit is contained in:
Jakub Piasecki
2024-11-08 11:07:26 -08:00
committed by Facebook GitHub Bot
parent e3c3a0c8a7
commit ee7b4e2763
3 changed files with 2 additions and 9 deletions
@@ -3182,7 +3182,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
}
@@ -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()
@@ -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()
}