Ошибка теста Espresso: AppNotIdleException

Я отключил все анимации в настройках разработчика. Но я все еще получаю это исключение при попытке щелкнуть по одной из кнопок.

Мое приложение действительно активно, а не простое, но я не могу его изменить.

android.support.test.espresso.AppNotIdleException: Looped for 6930
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:92)
 at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56)
 at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
 at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
 at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)

Ответы

Ответ 1

Я боролся с этой проблемой в течение последних нескольких дней.
Вот метод, который я использовал для идентификации "нарушителей":

private void dumpThreads() {
    int activeCount = Thread.activeCount();
    Thread[] threads = new Thread[activeCount];
    Thread.enumerate(threads);
    for (Thread thread : threads) {
        System.err.println(thread.getName() + ": " + thread.getState());
        for (StackTraceElement stackTraceElement : thread.getStackTrace()) {
            System.err.println("\t" + stackTraceElement);
        }
    }
}

В моем случае Facebook SDK использовал пул потоков AsyncTask.

Ответ 2

По ответ MaciejGórski по аналогичному вопросу:

Это было ошибкой в ​​моем коде приложения, где SwipeRefreshLayout анимированный само по себе бесконечно. Из-за ошибка в этом Компонент, состояние обновления даже не показывалось.

Ответ 3

Вы можете проверить это путем:

способ 1: отключить анимацию в настройках разработчика:

Setting -> developer options -> Window animation scale -> off

                                Transition animation scale -> off

                                Animator duration scale -> off

способ 2: если у вас есть customView в build.gradle, используйте это

defaultConfig {

   //...

   testOptions {
      animationsDisabled = true
   }

}

Ответ 4

В моем случае эта проблема возникала с AnimatedVectorDrawable и была вызвана objectAnimator, который был настроен на бесконечное повторение анимации (android:repeatCount="infinite")..

Проблема также присутствовала только на старых версиях платформы. Тесты прекрасно работали на Android 9, в то время как проблема была воспроизводимой на Android 5 и 6 (в данный момент не совсем точно с 7 и 8).

Я полагаю, что основная причина проблемы та же, что и для неопределенных индикаторов выполнения (рассматривается в этом вопросе). Тем не менее, я не нашел хорошего решения, только обходные пути.

Одним из обходных путей является обнаружение того, что анимация отключена (продолжительность аниматора равна 0) в настройках, и не запускать анимацию. Конечно, это работает только для версий платформы, где анимация не запускается автоматически.

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
}

Примечание. Уровень API 26 представил статический метод ValueAnimator.areAnimatorsEnabled(), который был бы полезен, если бы проблема возникала не только на старых версиях платформы.