question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Fatal Exception: java.lang.StackOverflowError ~8mb

See original GitHub issue

Lottie version: 3.7.1 Devices affected: Galaxy A71, Galaxy S20, Mi A2, GCE x86 phone and Pixel 5 OS affected: Android 9, 10, 11

I can’t reproduce this behaviour on my device (Pixel 3a) nor on the emulator, so I won’t provide a sample repo, I’m receiving this errors via Crashlytics (Firebase). I’ll share the code and logic here.

Describe the bug

Fatal Exception: java.lang.StackOverflowError: stack size 8192KB
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:33)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:636)
       at ....WalkThroughFragment$onViewCreated$1$1.onAnimationEnd(WalkThroughFragment.java:37)
       at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:554)
       at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:74)
       at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:222)
       at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:463)
       at com.airbnb.lottie.LottieDrawable$2.run(LottieDrawable.java:452)
       at com.airbnb.lottie.LottieDrawable.setComposition(LottieDrawable.java:230)
       at com.airbnb.lottie.LottieAnimationView.setComposition(LottieAnimationView.java:586)
       at com.airbnb.lottie.LottieAnimationView$2.onResult(LottieAnimationView.java:85)
       at com.airbnb.lottie.LottieAnimationView$2.onResult(LottieAnimationView.java:83)
       at com.airbnb.lottie.LottieTask.notifySuccessListeners(LottieTask.java:148)
       at com.airbnb.lottie.LottieTask.access$100(LottieTask.java:28)
       at com.airbnb.lottie.LottieTask$1.run(LottieTask.java:135)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7403)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

This walkThrough logic is an Activity with a ViewPager and 4 Fragments. Each Fragment has the following layout:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/const_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="@dimen/lottie_height_guideline_percent" />

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/walkthrough_step_Lottie"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/const_guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:lottie_autoPlay="true"
        app:lottie_imageAssetsFolder="lottie_images/"
        app:lottie_loop="false"
        app:lottie_rawRes="@raw/lottie_walkthrough_X" />

    <TextView
        style="@style/App.WidgetStyle.Title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/spacing_default"
        android:layout_marginTop="19dp"
        android:layout_marginEnd="@dimen/spacing_default"
        android:fontFamily="@font/open_sans_bold"
        android:gravity="center"
        android:text="@string/lbl_walkthrough_stepX"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/const_guideline" />

</androidx.constraintlayout.widget.ConstraintLayout>

Also, we have a loop logic to play the animation from the beginning until the end, and then infinitely loop between X and Y frames:

Example for Step 1:

class AppWalkThroughStep1Fragment : WalkThroughFragment() {

    override fun getMinFrame(): Int = 75
    override fun getMaxFrame(): Int = 150
    override fun getLottieviewId(): Int = R.id.walkthrough_step_Lottie

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_walkthrough_step1, container, false)
    }
}

abstract class WalkThroughFragment : Fragment() {

    abstract fun getMinFrame(): Int
    abstract fun getMaxFrame(): Int
    abstract fun getLottieviewId(): Int

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.findViewById<LottieAnimationView>(getLottieviewId())?.let { lottie ->
            lottie.addAnimatorListener(object : Animator.AnimatorListener {
                override fun onAnimationCancel(animation: Animator?) {
                    //unused
                }

                override fun onAnimationStart(animation: Animator?) {
                    //unused
                }

                override fun onAnimationRepeat(animation: Animator?) {
                    //unused
                }

                override fun onAnimationEnd(animation: Animator?) {
                    lottie.cancelAnimation()
                    lottie.setMinFrame(getMinFrame())
                    lottie.setMaxFrame(getMaxFrame())
                    lottie.repeatCount = LottieDrawable.INFINITE
                    lottie.playAnimation()
                }
            })
        }
        setHasOptionsMenu(false)
    }
}

note: the app:lottie_imageAssetsFolder .png files have sizes of: 53.94kB, 14.95kB, 56.91kB and 31.11kB

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
gpealcommented, Sep 8, 2021

@GuilhE For that, I think you could just set it to repeat forever then in onAnimationEnd, set minFrame to B

1reaction
gpealcommented, Sep 8, 2021

You can test this yourself by setting the animation duration scale to 0 in developer settings.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fatal Exception: java.lang.StackOverflowError stack size 8MB ...
This is a very rare bug that's happening in my app. Users open SettingsActivity and notice the app has frozen, after which it...
Read more >
java.lang.StackOverflowError: stack size 8MB Problem - Discuss
Typically, this is caused when your recursive functions doesn't have the correct termination condition, so it ends up calling itself forever. Or ...
Read more >
java.lang.StackOverflowError: stack size 8MB
Typically, you'll get a stack overflow if you are recursively calling a function and either don't have an escape or you call it...
Read more >
StackOverflowError - Android Developers
Android Developers. Docs More. Platform Android Studio Google ... java.util.concurrent.atomic ... Constructs a StackOverflowError with no detail message.
Read more >
How to Fix java.lang.StackOverflowError in Java - Rollbar
The java.lang.StackOverflowError is a runtime error which points to serious problems that cannot be caught by an application. The java.lang.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found