-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ChoreographerCallback double execution #4579
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good but please take a look at my comments prior to merging.
android/src/main/java/com/swmansion/reanimated/NodesManager.java
Outdated
Show resolved
Hide resolved
## Summary This PR fixes an issue with long animations. On Android, it was possible to execute ChoreographerCallback twice during the same frame (after frame drop). In effect, existing animations were canceled due to this if-condition in `requestAnimationFrame` method: ```js nativeRequestAnimationFrame((timestamp) => { if (lastNativeAnimationFrameTimestamp >= timestamp) { // Make sure we only execute the callbacks once for a given frame return; } ... ``` To fix it, I moved this check to the native code. When double execution happens I skip the execution of the JS callback, but I still need to schedule another choreographer callback. ## How to test it? ```java final long[] lastTimestamp = {0}; new GuardedFrameCallback(context) { @OverRide protected void doFrameGuarded(long frameTimeNanos) { if (lastTimestamp[0] == frameTimeNanos) { Log.w("test"); } onAnimationFrame(frameTimeNanos); lastTimestamp[0] = frameTimeNanos; } } ``` ### Before - Open SVGExample - Set a breakpoint in Android Studio at line `Log.w("test");` - Wait some time until the breakpoint hit - Pass breakpoint - Animation will **stop** ❌ ### After - Open SVGExample - Set a breakpoint in Android Studio at line `Log.w("test");` - Wait some time until the breakpoint hit - Pass breakpoint - Animation will **keep going** ✅
I'm not 100% sure if this really is related but I want to inform you nonetheless: After some investigating I think the behaviour is like this:
Unfortunately I can not provide a reproducible demo right now due to lack of time and my project is very complex, but maybe it helps in case there are other hints to a possible issue. Edit: To be clear this issue is not happening on 2.14.4 |
Hey @tlow92 👋 Thanks for your report! It seems like a different problem, could you open a new issue with it? |
Summary
This PR fixes an issue with long animations. On Android, it was possible to execute ChoreographerCallback twice during the same frame (after frame drop). In effect, existing animations were canceled due to this if-condition in
requestAnimationFrame
method:To fix it, I moved this check to the native code. When double execution happens I skip the execution of the JS callback, but I still need to schedule another choreographer callback.
How to test it?
Before
Log.w("test");
After
Log.w("test");