问题背景:
有个动画在 onAnimatorEnd
回调中间接调用了 Animator#cancel
。在 Android 8 没有问题,但是在 Android 5, Android 6 等版本出现了下面的递归调用。
java.lang.StackOverflowError: stack size 8MB
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
...
at android.animation.AnimatorSet.cancel(AnimatorSet.java:340)
发现是 AnimatorSet 造成的问题,AnimatorSet 在 Android 8 和 Android 8 以下对 cancel 方法的实现有区别。
Android 8 及以上 | Android 8 以下 |
---|---|
回调了 onAnimationCancel 之后,不会再回调 onAnimatioinEnd | 回调了 onAnimationCancel 之后,会再回调 onAnimatioinEnd |
解决方法:
- 避免存在
onAnimationEnd
中会调用cancel
的场景 - 在 onAnimationEnd 调用之后,移除对应的 listener