循环 AnimationSet 会导致 StackOverflowError
Looping an AnimationSet causes StackOverflowError
我正在删除一个 android 应用程序,其中有一个无限重复的动画导致 WhosebugError。当同一对象上的另一个动画开始时,它会执行此操作。
private fun pulse() {
val randomGenerator = Random()
val durationx = randomGenerator.nextInt(4000) + 1500
val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
}
val inflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.3f).apply {
duration = durationx.toLong()
}
val deflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.0f).apply {
duration = durationx.toLong()
}
val deflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.0f).apply {
duration = durationx.toLong()
}
val rotate = ObjectAnimator.ofFloat(mContentView, "rotation", 1.0f).apply {
duration = durationx.toLong()
}
val soulToButton = AnimatorSet().apply {
play(inflateX).with(inflateY)
play(rotate).with(inflateX)
play(deflateX).after(inflateX)
play(deflateY).after(inflateY)
start()
}
soulToButton.addListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
soulToButton.start() // stacktrace points to this line as cause for the error.
}
})
soulToButton.start()
AnimatorSet().apply {
play(soulToButton)
start()
}
}
我尝试将函数更改为 fun pulse(stop: boolean)
,在其他动画开始之前调用 pulse(false)
来启动脉冲和 pulse(true)
,并在几个地方添加 if (stop) {soulToButton.cancel()}
。我还尝试换行导致这样的错误:while(stop == false){soultoButton.start()}
所有这些都没有帮助。
它是 Kotlin,但它仍然是 Java,所有 JVM 限制都与此相关。因此,由于 JVM 堆栈有限,您不能无限期地调用一个函数而不会导致 WhosebugError。
有一些特殊功能可以帮助您无限期地 运行 动画。例如
objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
或者你的情况
ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
以相同方式修改所有动画并将它们链接到 AnimatorSet
后,其 start
函数将无限期播放此动画,而不会发生 WhosebugError。
希望对您有所帮助。
您正在尝试在此处完成后再次开始动画,
soulToButton.addListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
soulToButton.start() // This will start the animation again without an end to the animation hence the Whosebug error.
}
})
为了运行一个无限时间的动画使用下面的代码,
val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
val soulToButton = AnimatorSet().apply {
play(inflateX).with(inflateY)
play(rotate).with(inflateX)
play(deflateX).after(inflateX)
play(deflateY).after(inflateY)
}
soulToButton.start()
试试这个版本:它简短明了,基本上做同样的事情。
val randomGenerator = Random()
val durationx = randomGenerator.nextInt(4000) + 1500
val animator = animator@{ property : String, value : Float ->
return@animator ObjectAnimator.ofFloat(mContextView, property, value).apply {
duration = durationx.toLong()
repeatMode = REVERSE
repeatCount = INFINITE
}
}
AnimatorSet().apply {
playTogether(animator("scaleX", 1.3f),animator("scaleY", 1.3f),animator("rotation", 45.0f))
start()
}
我正在删除一个 android 应用程序,其中有一个无限重复的动画导致 WhosebugError。当同一对象上的另一个动画开始时,它会执行此操作。
private fun pulse() {
val randomGenerator = Random()
val durationx = randomGenerator.nextInt(4000) + 1500
val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
}
val inflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.3f).apply {
duration = durationx.toLong()
}
val deflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.0f).apply {
duration = durationx.toLong()
}
val deflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.0f).apply {
duration = durationx.toLong()
}
val rotate = ObjectAnimator.ofFloat(mContentView, "rotation", 1.0f).apply {
duration = durationx.toLong()
}
val soulToButton = AnimatorSet().apply {
play(inflateX).with(inflateY)
play(rotate).with(inflateX)
play(deflateX).after(inflateX)
play(deflateY).after(inflateY)
start()
}
soulToButton.addListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
soulToButton.start() // stacktrace points to this line as cause for the error.
}
})
soulToButton.start()
AnimatorSet().apply {
play(soulToButton)
start()
}
}
我尝试将函数更改为 fun pulse(stop: boolean)
,在其他动画开始之前调用 pulse(false)
来启动脉冲和 pulse(true)
,并在几个地方添加 if (stop) {soulToButton.cancel()}
。我还尝试换行导致这样的错误:while(stop == false){soultoButton.start()}
所有这些都没有帮助。
它是 Kotlin,但它仍然是 Java,所有 JVM 限制都与此相关。因此,由于 JVM 堆栈有限,您不能无限期地调用一个函数而不会导致 WhosebugError。
有一些特殊功能可以帮助您无限期地 运行 动画。例如
objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
或者你的情况
ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
以相同方式修改所有动画并将它们链接到 AnimatorSet
后,其 start
函数将无限期播放此动画,而不会发生 WhosebugError。
希望对您有所帮助。
您正在尝试在此处完成后再次开始动画,
soulToButton.addListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
soulToButton.start() // This will start the animation again without an end to the animation hence the Whosebug error.
}
})
为了运行一个无限时间的动画使用下面的代码,
val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
val soulToButton = AnimatorSet().apply {
play(inflateX).with(inflateY)
play(rotate).with(inflateX)
play(deflateX).after(inflateX)
play(deflateY).after(inflateY)
}
soulToButton.start()
试试这个版本:它简短明了,基本上做同样的事情。
val randomGenerator = Random()
val durationx = randomGenerator.nextInt(4000) + 1500
val animator = animator@{ property : String, value : Float ->
return@animator ObjectAnimator.ofFloat(mContextView, property, value).apply {
duration = durationx.toLong()
repeatMode = REVERSE
repeatCount = INFINITE
}
}
AnimatorSet().apply {
playTogether(animator("scaleX", 1.3f),animator("scaleY", 1.3f),animator("rotation", 45.0f))
start()
}