Search code examples
javaandroidloopsanimationstack-overflow

Loop in value animator cause in crash with java.lang.StackOverflowError: stack size 8MB


I using two value animation and in end of one i start another. It is work fine on my tested devices but get java.lang.StackOverflowError: stack size 8MB on many devices in live.

this is how i used value animator:

 ObjectAnimator fadeOut = ObjectAnimator.ofInt(drawableIcon, "alpha", 255, 0);
 ObjectAnimator fadeIn = ObjectAnimator.ofInt(drawableIcon, "alpha", 0, 255);

    fadeIn.setDuration(300);
    fadeOut.setDuration(300);
    fadeOut.setStartDelay(500);

    fadeIn.start();

    fadeIn.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            fadeOut.start();
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

    fadeOut.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            fadeIn.start();
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

I googled but coul not find any reason and solution. Is any body have any idea?


Solution

  • You should repeat animation instead of creating a loop dependency between them. Use AnimatorSet to do that:

        AnimatorSet animatorSet = new AnimatorSet();
        ObjectAnimator fadeIn = ObjectAnimator.ofInt(drawableIcon, "alpha", 0, 255);
        ObjectAnimator fadeOut = ObjectAnimator.ofInt(drawableIcon, "alpha", 255, 0);
        fadeIn.setDuration(300);
        fadeOut.setDuration(300);
        fadeOut.setStartDelay(500);
    
        animatorSet.playSequentially(fadeIn, fadeOut);
        animatorSet.setDuration(1100);
        animatorSet.addListener(new AnimatorListenerAdapter() {
    
            private boolean mCanceled;
    
            @Override
            public void onAnimationStart(Animator animation) {
                mCanceled = false;
            }
    
            @Override
            public void onAnimationCancel(Animator animation) {
                mCanceled = true;
            }
    
            @Override
            public void onAnimationEnd(Animator animation) {
                if (!mCanceled) {
                    animation.start();
                }
            }
    
        });
        animatorSet.start();
    

    Here is the result:

    enter image description here