diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.kt index 2f50b0be04f..7d2bc409574 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.kt @@ -80,7 +80,7 @@ import kotlin.concurrent.Volatile */ @OptIn(UnstableReactNativeAPI::class) @ReactModule(name = NativeAnimatedModuleSpec.NAME) -public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : +public class NativeAnimatedModule(reactContext: ReactApplicationContext) : NativeAnimatedModuleSpec(reactContext), LifecycleEventListener, UIManagerListener { // For `queueAndExecuteBatchedOperations` @@ -163,12 +163,13 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : // Due to a race condition, we manually "carry-over" a polled item from previous batch // instead of peeking the queue itself for consistency. // TODO(T112522554): Clean up the queue access + val peekedOperation = peekedOperation if (peekedOperation != null) { - if (checkNotNull(peekedOperation).batchNumber > maxBatchNumber) { + if (peekedOperation.batchNumber > maxBatchNumber) { break } - operations.add(checkNotNull(peekedOperation)) - peekedOperation = null + operations.add(peekedOperation) + this.peekedOperation = null } val polledOperation = @@ -179,7 +180,7 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : if (polledOperation.batchNumber > maxBatchNumber) { // Because the operation is already retrieved from the queue, there's no way of placing it // back as the head element, so we remember it manually here - peekedOperation = polledOperation + this.peekedOperation = polledOperation break } operations.add(polledOperation) @@ -189,8 +190,7 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : } } - private val animatedFrameCallback: GuardedFrameCallback - private val reactChoreographer: ReactChoreographer? = ReactChoreographer.getInstance() + private val reactChoreographer: ReactChoreographer = ReactChoreographer.getInstance() private val operations = ConcurrentOperationQueue() private val preOperations = ConcurrentOperationQueue() @@ -205,7 +205,6 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : private var initializedForFabric = false private var initializedForNonFabric = false - private var enqueuedAnimationOnFrame = false @UIManagerType private var uiManagerType = UIManagerType.LEGACY private var numFabricAnimations = 0 @@ -302,8 +301,8 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : } } - checkNotNull(preOperations).executeBatch(batchNumber, nodesManager) - checkNotNull(operations).executeBatch(batchNumber, nodesManager) + preOperations.executeBatch(batchNumber, nodesManager) + operations.executeBatch(batchNumber, nodesManager) } // For non-FabricUIManager only @@ -322,11 +321,9 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : // might be stripped out. val frameNo = currentBatchNumber++ - val preOperationsUIBlock = UIBlock { - checkNotNull(preOperations).executeBatch(frameNo, nodesManager) - } + val preOperationsUIBlock = UIBlock { preOperations.executeBatch(frameNo, nodesManager) } - val operationsUIBlock = UIBlock { checkNotNull(operations).executeBatch(frameNo, nodesManager) } + val operationsUIBlock = UIBlock { operations.executeBatch(frameNo, nodesManager) } assert(uiManager is UIManagerModule) val uiManagerModule = uiManager as UIManagerModule @@ -366,41 +363,34 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : nodesManagerRef.set(nodesManager) } - init { - animatedFrameCallback = - object : GuardedFrameCallback(checkNotNull(reactContext)) { - override fun doFrameGuarded(frameTimeNanos: Long) { - try { - enqueuedAnimationOnFrame = false - val nodesManager = nodesManager - if (nodesManager?.hasActiveAnimations() == true) { - nodesManager.runUpdates(frameTimeNanos) - } - // This is very unlikely to ever be hit. - if (nodesManager == null || reactChoreographer == null) { - return - } - - enqueueFrameCallback() - } catch (ex: Exception) { - throw RuntimeException(ex) + private var enqueuedAnimationOnFrame = false + private val animatedFrameCallback = + object : GuardedFrameCallback(reactContext) { + override fun doFrameGuarded(frameTimeNanos: Long) { + try { + enqueuedAnimationOnFrame = false + val nodesManager = nodesManager ?: return + if (nodesManager.hasActiveAnimations()) { + nodesManager.runUpdates(frameTimeNanos) } + + enqueueFrameCallback() + } catch (ex: Exception) { + throw RuntimeException(ex) } } - } + } private fun clearFrameCallback() { - checkNotNull(reactChoreographer) - .removeFrameCallback( - ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, animatedFrameCallback) + reactChoreographer.removeFrameCallback( + ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, animatedFrameCallback) enqueuedAnimationOnFrame = false } private fun enqueueFrameCallback() { if (!enqueuedAnimationOnFrame) { - checkNotNull(reactChoreographer) - .postFrameCallback( - ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, animatedFrameCallback) + reactChoreographer.postFrameCallback( + ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, animatedFrameCallback) enqueuedAnimationOnFrame = true } } @@ -431,8 +421,9 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext?) : } // Subscribe to UIManager (Fabric or non-Fabric) lifecycle events if we haven't yet - if (if (uiManagerType == UIManagerType.FABRIC) initializedForFabric - else initializedForNonFabric) { + val initialized = + if (uiManagerType == UIManagerType.FABRIC) initializedForFabric else initializedForNonFabric + if (initialized) { return }