3

I have the following animated vector drawable:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_ventilation" >
    <target
        android:name="fan_group"
        android:animation="@animator/fan_rotation_animation" />
</animated-vector>

It just animated a fan using a rotation animation.

I am setting this icon in an ImageView and controlling the start/stop animation calling the following method (nnly in Lollipop and high):

public void setStopped(boolean stopped) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        this.setImageResource(R.drawable.ic_ventilation_animated);
        Drawable drawable = this.getDrawable();
        if (drawable instanceof AnimatedVectorDrawableCompat) {
            if(stopped) {
                ((AnimatedVectorDrawableCompat) drawable).stop();
            } else {
                ((AnimatedVectorDrawableCompat) drawable).start();
            }
        }
    }
}

But I get the following exception:

android.support.test.espresso.AppNotIdleException: Looped for 3654 iterations over 60 SECONDS. The following Idle Conditions failed .
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:580)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:88)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:51)
at android.support.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:312)
at android.support.test.espresso.ViewInteraction.desugaredPerform(ViewInteraction.java:173)
at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:114)

I have disabled animations in the developer options menu, like explained here. With the animations disabled, I see that the icon doesn't animate anymore after calling ((AnimatedVectorDrawableCompat) drawable).start();. However, the the exception is raised.

Is there a problem when calling the ((AnimatedVectorDrawableCompat) drawable).start(); method even when animations are disabled? How can I fix this so I can run my tests without need to care about the animation?

amp
  • 11,754
  • 18
  • 77
  • 133

1 Answers1

2

In my case this problem was caused by an objectAnimator that was set to repeat the animation infinitely (android:repeatCount="infinite").

The problem was also present only on older platform versions. Tests were perfectly working on Android 9 while the problem was reproducible on Android 5 and 6 (not sure about 7 and 8 at the moment).

I believe, the root cause of the problem is the same as for indeterminate progress bars (covered in this SO question). However, I haven't found any nice solution, only workarounds.

One of the workarounds is to detect that the animation is turned off (animator duration is 0) in the setting and don't start the animation. Of course, this only works for platform versions where the animation does not autostart.

private fun startIconAnimation(imageView: ImageView) {
    if (areAnimationsEnabled()) {
        (imageView.drawable as Animatable).start()
    }
}

private fun areAnimationsEnabled(): Boolean {
    val animatorDurationScale = Settings.Global.getFloat(
        requireContext().contentResolver,
        Settings.Global.ANIMATOR_DURATION_SCALE,
        1.0f
    )
    return animatorDurationScale != 0.0f
}

Note: API level 26 introduced a static method ValueAnimator.areAnimatorsEnabled() which would have been handy if the problem was not happening only on the older platform versions.

Josef Adamcik
  • 5,620
  • 3
  • 36
  • 42