From ef9d1fba237c08a158c8f32e823f229921e7c052 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Thu, 22 Feb 2018 13:26:32 -0800 Subject: [PATCH] Fix IllegalStateException in looped timing native animation Summary: This PR fixes regression introduced in #17896 with IllegalStateException being thrown in FrameBasedAnimationDriver. After investigating it seemed that the root cause was the code responsible for looping animations that was setting next frame time by adding the frame interval to the current time. In some circumstances the next frame would run earlier than that and as a result the calculated frame index was negative. Here is the stacktrace as reported by axemclion https://github.com/facebook/react-native/pull/17896/files#r170007224 ``` Caused by: java.lang.IllegalStateException: Calculated frame index should never be lower than 0 at com.facebook.react.animated.FrameBasedAnimationDriver.runAnimationStep(FrameBasedAnimationDriver.java:60) at com.facebook.react.animated.NativeAnimatedNodesManager.runUpdates(NativeAnimatedNodesManager.java:444) at com.facebook.react.animated.NativeAnimatedModule$1.doFrameGuarded(NativeAnimatedModule.java:100) at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29) ``` Run native animated tests suite. Run RNTester and scroll to the loop animation and see it working correctly [ANDROID][BUGFIX][Animated] - Fix exception thrown by timing animation when looping Closes https://github.com/facebook/react-native/pull/18061 Differential Revision: D7059335 Pulled By: hramos fbshipit-source-id: b08dfd1398d028eeeabeb11863743666379da374 --- .../facebook/react/animated/FrameBasedAnimationDriver.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/FrameBasedAnimationDriver.java b/ReactAndroid/src/main/java/com/facebook/react/animated/FrameBasedAnimationDriver.java index d243fd8f45c940..f8fca1f9d22921 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/FrameBasedAnimationDriver.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/FrameBasedAnimationDriver.java @@ -52,7 +52,10 @@ public void resetConfig(ReadableMap config) { public void runAnimationStep(long frameTimeNanos) { if (mStartFrameTimeNanos < 0) { mStartFrameTimeNanos = frameTimeNanos; - mFromValue = mAnimatedValue.mValue; + if (mCurrentLoop == 1) { + // initiate start value when animation runs for the first time + mFromValue = mAnimatedValue.mValue; + } } long timeFromStartMillis = (frameTimeNanos - mStartFrameTimeNanos) / 1000000; int frameIndex = (int) Math.round(timeFromStartMillis / FRAME_TIME_MILLIS); @@ -66,7 +69,7 @@ public void runAnimationStep(long frameTimeNanos) { if (frameIndex >= mFrames.length - 1) { nextValue = mToValue; if (mIterations == -1 || mCurrentLoop < mIterations) { // looping animation, return to start - mStartFrameTimeNanos = frameTimeNanos + ((long) FRAME_TIME_MILLIS) * 1000000L; + mStartFrameTimeNanos = -1; mCurrentLoop++; } else { // animation has completed, no more frames left mHasFinished = true;