ValueAnimator 执行时序在Android4.4的版本差异踩坑

426 阅读1分钟

问题一

在项目中自定义View的时候,难免会使用到ValueAnimator实现一些动画效果,开始动画时在其回调的onAnimationStart()/onAnimationUpdate()中做一些业务逻辑,笔者这里有个业务逻辑是在onAnimationStart()先做xxx,然后在onAnimationUpdate()做xxx,有时序依赖,本来在Android 9.0等高版本上跑都正常,但是在Android 4.4上跑就有问题了,通过源码分析,发现回调时序如下:

  • Android 9: onAnimationStart() -> onAnimationUpdate()
  • Android 4.4: onAnimationUpdate() -> onAnimationStart()

Android 9源码分析

  1. 可以看到调用ValueAnimator.start()流程中,执行:startAnimation()->setCurrentPlayTime(0);

image.png

  1. startAnimation()这里往下走会走到onAnimationStart()回调

image.png

image.png

  1. setCurrentPlayTime(0)这里往下走会走到onAnimationUpdate()回调

image.png

image.png

  1. 所以在Android 9上ValueAnimator开始执行动画时回调顺序确实是onAnimationStart()->onAnimationUpdate()

Android 4.4源码分析

  1. 可以看到调用ValueAnimator.start()流程中,执行:setCurrentPlayTime(0)-> notifyStartListeners();;
  2. 同上,setCurrentPlayTime(0)这里往下走会走到onAnimationUpdate()回调
  3. notifyStartListeners()这里往下走会走到onAnimationStart()回调
  4. 所以在Android 4.4上ValueAnimator开始执行动画时回调顺序确实是onAnimationUpdate()->onAnimationStart()

image.png

问题二

ValueAnimator.onAnimationEnd()中调用ValueAnimator.isRunning()判断动画是否正在执行:

  • 在Android 9上返回false
  • 在Android 4.4上返回true

Android 9源码分析

  1. 可以看到ValueAnimator.isRunning()的值是由mRunning决定
  2. 在执行ValueAnimator.onAnimationEnd()回调之前mRunning置为了false
  3. 所以在Android 9上返回false

image.png

image.png

Android 4.4源码分析

  1. 可以看到ValueAnimator.isRunning()的值是由mRunningmPlayingState == RUNNING两个值有一个为true决定
  2. 在执行ValueAnimator.onAnimationEnd()回调的时候mRunning此时还是为true(在之后才置为true),所以此时ValueAnimator.isRunning()还是返回true;

image.png

image.png