当我想在上一个动画完成后为下一个动画获取转换()时,我也遇到了这个问题,然后无限循环导致堆栈溢出。
我从GrepCode分析了 Android 源代码的问题,下面的代码getTransformation()
,我从来没有发现任何会导致无限循环的问题,因为只有地方调用 onAnimationEnd()
,它会设置mEnded
为 true。下次调用getTransformation()
,应该会被 阻止if(!mEnded)
,但事实并非如此。
if (expired) {
if (mRepeatCount == mRepeated) {
if (!mEnded) {
mEnded = true; //this is not real!!!
if (mListener != null) {
mListener.onAnimationEnd(this);
}
}
} else {
if (mRepeatCount > 0) {
mRepeated++;
}
if (mRepeatMode == REVERSE) {
mCycleFlip = !mCycleFlip;
}
mStartTime = -1;
mMore = true;
if (mListener != null) {
mListener.onAnimationRepeat(this);
}
}
}
它接缝 grepcode 与这段代码不正确。事实是,eEnded = true
在onAnimationEnd()
调用后设置:
if (!mEnded) {
if (mListener != null) {
mListener.onAnimationEnd(this);
}
//it happen after onAnimationEnd(). cancel() is also does as this
mEnded = true;
}
这应该可以解释为什么会发生无限循环。即使您检查animation.hasEnded()
也无济于事,因为它无法将 mEnded 设置为 true。
我解决这个问题的方法是:
在侦听器中设置标志以保护:
boolean needBlock = false;
public void onAnimationEnd(Animation animation)
{
if ( needBlock ) return;
needBlock = true;
Transformation t= new Transformation();
animation.getTransformation(animation.getDuration(), t);
}
清除 AnimationListner。如果需要,我们可以在之后设置
public void onAnimationEnd(Animation animation)
{
animation.setAnimationListener(null);
Transformation t= new Transformation();
animation.getTransformation(animation.getDuration(), t);
animation.setAnimationListener(this);
}