Skip to content
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

Attempt to invoke virtual method 'float java.lang.Float.floatValue()' on a null object reference in ColorKeyframeAnimation.getIntValue #2361

Closed
lsuski opened this issue Aug 17, 2023 · 3 comments · Fixed by #2407

Comments

@lsuski
Copy link

lsuski commented Aug 17, 2023

Stacktrace:

 java.lang.NullPointerException: Attempt to invoke virtual method 'float java.lang.Float.floatValue()' on a null object reference
                                         	at com.airbnb.lottie.animation.keyframe.ColorKeyframeAnimation.getIntValue(ColorKeyframeAnimation.java:30)
                                         	at com.airbnb.lottie.animation.keyframe.ColorKeyframeAnimation.getIntValue(ColorKeyframeAnimation.java:44)
                                         	at com.airbnb.lottie.animation.content.FillContent.draw(FillContent.java:101)
                                         	at com.airbnb.lottie.animation.content.ContentGroup.draw(ContentGroup.java:190)
                                         	at com.airbnb.lottie.animation.content.ContentGroup.draw(ContentGroup.java:190)
                                         	at com.airbnb.lottie.model.layer.ShapeLayer.drawLayer(ShapeLayer.java:37)
                                         	at com.airbnb.lottie.model.layer.BaseLayer.draw(BaseLayer.java:259)
                                         	at com.airbnb.lottie.model.layer.CompositionLayer.drawLayer(CompositionLayer.java:130)
                                         	at com.airbnb.lottie.model.layer.BaseLayer.draw(BaseLayer.java:259)
                                         	at com.airbnb.lottie.model.layer.CompositionLayer.drawLayer(CompositionLayer.java:130)
                                         	at com.airbnb.lottie.model.layer.BaseLayer.draw(BaseLayer.java:259)
                                         	at com.airbnb.lottie.LottieDrawable.renderAndDrawAsBitmap(LottieDrawable.java:1637)
                                         	at com.airbnb.lottie.LottieDrawable.draw(LottieDrawable.java:680)
                                         	at com.airbnb.lottie.compose.LottieAnimationKt$LottieAnimation$2.invoke(LottieAnimation.kt:129)
                                         	at com.airbnb.lottie.compose.LottieAnimationKt$LottieAnimation$2.invoke(LottieAnimation.kt:99)
                                         	at androidx.compose.ui.draw.DrawBackgroundModifier.draw(DrawModifier.kt:114)
                                         	at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:92)
                                         	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:370)
                                         	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:359)
                                         	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:236)
                                         	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:367)
                                         	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:359)
                                         	at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:866)
                                         	at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:151)
                                         	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:367)
                                         	at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:58)
                                         	at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:396)
                                         	at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:395)
                                         	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200)
                                         	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234)
                                         	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230)
                                         	at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
                                         	at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
                                         	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
                                         	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
                                         	at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:395)
                                         	at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:58)
                                         	at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
                                         	at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:301)
                                         	at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:242)
                                         	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:354)

Most likely this this happens when keyframe.endFrame is null which is possible value but valueCallback.getValueInternal expects endFrame to be nonnull float. It doesn't happen always

Steps To Reproduce
Steps to reproduce the behavior:

I have dynamic properties added to LottieAnimation for changing color

 val colorProperty = rememberLottieDynamicProperty(LottieProperty.COLOR, callback = LottieBrandColorSetter::replaceBrandColor, keyPath = arrayOf(LottieBrandColorSetter.keyPath))
    val strokeColorProperty = rememberLottieDynamicProperty(LottieProperty.STROKE_COLOR, callback = LottieBrandColorSetter::replaceBrandColor, keyPath = arrayOf(LottieBrandColorSetter.keyPath))

and

LottieAnimation(
...
    dynamicProperties = LottieDynamicProperties(listOf(colorProperty, strokeColorProperty))
)
@gpeal
Copy link
Collaborator

gpeal commented Sep 2, 2023

Can you attach an animation that reproduces this?

@lsuski
Copy link
Author

lsuski commented Sep 4, 2023

AFAIR It happened with few animations. I had a screen where I switched animations after clicking on buton but I'm not sure if it has anything to do with this bug. I'll try to reproduce this and go back to you

@lsuski
Copy link
Author

lsuski commented Sep 5, 2023

I couldn't reproduce this again. However I think that this problem is still possible due to differences in expected nullability in mentioned lottie functions

gpeal added a commit that referenced this issue Oct 30, 2023
It is not clear to me why or how this would happen. endFrame is technically nullable because of the order that parsing happens but it should be non-null by the time parsing finishes. This should be safe enough to add to fix this NPE though.

Fixes #2361
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants