致命异常:使用Lottie库时发生java.lang.StackOverflowError

问题描述

在我的SplashActicty中,我从远程API获取设置,并同时通过Lottie库显示动画,并且在动画的每个周期中,如果成功加载设置,我会将用户重定向到下一个活动,否则,我将再次播放动画,并且该周期将继续直到加载设置

我为某些用户获得了Fatal Exception: java.lang.StackOverflowError: stack size 8MB

此异常的原因是什么,我该如何解决

Firebase控制台崩溃日志堆栈跟踪

Fatal Exception: java.lang.StackOverflowError: stack size 8MB
           at com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation.getCurrentKeyframe(BaseKeyframeAnimation.java:86)
           at com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation.setProgress(BaseKeyframeAnimation.java:60)
           at com.airbnb.lottie.animation.keyframe.TransformKeyframeAnimation.setProgress(TransformKeyframeAnimation.java:124)
           at com.airbnb.lottie.model.layer.BaseLayer.setProgress(BaseLayer.java:491)
           at com.airbnb.lottie.model.layer.CompositionLayer.setProgress(CompositionLayer.java:130)
           at com.airbnb.lottie.model.layer.CompositionLayer.setProgress(CompositionLayer.java:148)
           at com.airbnb.lottie.model.layer.CompositionLayer.setProgress(CompositionLayer.java:148)
           at com.airbnb.lottie.model.layer.CompositionLayer.setProgress(CompositionLayer.java:148)
           at com.airbnb.lottie.LottieDrawable$1.onAnimationUpdate(LottieDrawable.java:73)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyUpdate(BaseLottieAnimator.java:88)
           at com.airbnb.lottie.utils.LottieValueAnimator.setFrame(LottieValueAnimator.java:158)
           at com.airbnb.lottie.utils.LottieValueAnimator.playAnimation(LottieValueAnimator.java:207)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:387)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieAnimationView.playAnimation(LottieAnimationView.java:511)
           at com.beroozresaan.android.ui.splash.SplashActivity$1.onAnimationEnd(SplashActivity.java:196)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
           at com.airbnb.lottie.utils.BaseLottieAnimator.notifyEnd(BaseLottieAnimator.java:73)
           at com.airbnb.lottie.utils.LottieValueAnimator.endAnimation(LottieValueAnimator.java:216)
           at com.airbnb.lottie.LottieDrawable.playAnimation(LottieDrawable.java:391)
           at com.airbnb.lottie.LottieDrawable$2.run(LottieDrawable.java:380)
           at com.airbnb.lottie.LottieDrawable.setComposition(LottieDrawable.java:226)
           at com.airbnb.lottie.LottieAnimationView.setComposition(LottieAnimationView.java:460)
           at com.beroozresaan.android.ui.splash.SplashActivity.lambda$loadDefaultFromAssets$1$SplashActivity(SplashActivity.java:136)
           at com.beroozresaan.android.ui.splash.-$$Lambda$SplashActivity$Ggdzqtz0YkoM-aNiOz71rE-ohzo.onResult(:4)
           at com.airbnb.lottie.LottieTask.notifySuccessListeners(LottieTask.java:144)
           at com.airbnb.lottie.LottieTask.access$100(LottieTask.java:27)
           at com.airbnb.lottie.LottieTask$1.run(LottieTask.java:131)
           at android.os.Handler.handleCallback(Handler.java:873)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loop(Looper.java:201)
           at android.app.ActivityThread.main(ActivityThread.java:6810)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

SplashActivity.java


public class SplashActivity extends AppCompatActivity implements ErrorDialogFragment.OnErrorActionListener {

    @Inject
    viewmodelFactory viewmodelFactory;

    private Settingviewmodel settingviewmodel;
    private ActivitySplashBinding mBinding;
    private boolean settingIsLoaded = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mBinding = DataBindingUtil.setContentView(this,R.layout.activity_splash);
        settingviewmodel = viewmodelProviders.of(this,viewmodelFactory).get(Settingviewmodel.class);

        subscribeSettingResponse();

        setAnimationListener();
    }

    private void loadSetting() {
        settingviewmodel.loadSetting();
    }

    private void subscribeSettingResponse() {
        settingviewmodel.getSettingResponse().observe(this,dataWrapper -> {
            switch (dataWrapper.status) {
                case SUCCESS:
                    settingIsLoaded = true;
                    break;
                case ERROR:
                case SERVER_ERROR:
                case CONNECTION_ERROR:
                    ErrorDialogFragment.showError(getSupportFragmentManager(),MessageMap.exceptionParser(this,dataWrapper),this);
                    break;
                default:
                    break;
            }
        });
    }

    private void startMainActivity() {
        Intent intent = new Intent(this,MainActivity.class);
        if (getIntent() != null && getIntent().getExtras() != null)
            intent.putExtras(getIntent().getExtras());
        startActivity(intent);
        finish();
    }

    @Override
    protected void onPause() {
        super.onPause();
        settingviewmodel.getSettingResponse().removeObservers(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        playSplash();
        loadSetting();
    }
    

    private void playSplash() {
        String splashAnimationFileName = "splash_default.json";
        LottieTask lottieCompositionLottieTask = LottieCompositionFactory.fromAsset(this,splashAnimationFileName);

        lottieCompositionLottieTask.addListener(result1 -> {
            mBinding.animationLottie.setComposition(result1);
            mBinding.animationLottie.playAnimation();
        });

        lottieCompositionLottieTask.addFailureListener(result -> {
            Timber.e(result);
            startMainActivity();
        });

        mBinding.animationLottie.addAnimatorUpdateListener(animation -> {
            if (animation.isRunning()) {
                mBinding.animationLottie.removeAllUpdateListeners();
            }
        });

        mBinding.animationLottie.setFailureListener(result -> {
            Timber.e(result);
            startMainActivity();
        });

    }

    private void setAnimationListener() {
        mBinding.animationLottie.addAnimatorListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                Timber.e("animation started");
            }

            @SuppressLint("CheckResult")
            @Override
            public void onAnimationEnd(Animator animation) {
                if (settingIsLoaded) {
                    startMainActivity();
                } else {
                    mBinding.animationLottie.playAnimation();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                Timber.e("animation repeated");
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mBinding != null) {
            mBinding.animationLottie.removeAllUpdateListeners();
            mBinding.animationLottie.removeAllLottieOnCompositionLoadedListener();
            mBinding.animationLottie.removeAllAnimatorListeners();
            mBinding = null;
        }

    }
}

activity_splash.xml

<?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
        <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/animation_lottie"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:lottie_autoplay="true"
            app:lottie_enableMergePathsForKitKatandAbove="false"
            app:lottie_renderMode="automatic"
            app:lottie_speed="1" />
 </layout>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)