Приложение может слишком много работать над своей основной нитью

Я новичок в среде Android SDK / API. Это первая попытка рисовать график / график. Я попытался использовать различные типы образцов кода эмулятора, используя 3 разных бесплатных библиотеки, ничего не отображается на экране макета. Logcat повторяет следующее сообщение:

  W / Trace (1378): Неожиданное значение из nativeGetEnabledTags: 0
  I / Хореограф (1378): пропустил 55 кадров!  Приложение может делать слишком много работы над своей основной нитью. 

Проблема не сохранялась, и диаграмма работала, когда я запускал образец кода, относящийся к оценочной копии лицензированной библиотеки.

Взято из: Android UI: Исправление пропущенных кадров

Любой, кто начинает разрабатывать приложение для Android, видит это сообщение на logcat «Хореограф (abc): пропущенные xx кадры! Приложение может делать слишком много работы над своим основным потоком ». Итак, что это на самом деле означает, почему вы должны беспокоиться и как его решать.

Это означает, что ваш код требует много времени для обработки, и из-за него пропускаются кадры. Возможно, из-за некоторой тяжелой обработки, которую вы делаете в основе вашего приложения или доступа к БД или любой другой вещи, которая вызывает поток Остановитесь некоторое время. Вот более подробное объяснение:

Хореограф позволяет приложениям подключаться к vsync и правильно использовать время для повышения производительности.

Анимация Android-просмотра внутри использует хореографа с той же целью: правильно настроить анимацию и, возможно, улучшить производительность.

Поскольку хореографу рассказывают о каждом событии vsync, я могу сказать, не работает ли один из Runnables хореографом.post * apis за один кадр, в результате чего кадры будут пропущены.

По моему пониманию, хореограф может обнаруживать проскальзывание кадра. Он не может объяснить, почему это происходит.

Сообщение «Приложение может делать слишком много работы над основным потоком». Возможно, это вводит в заблуждение.

Источник: Значение сообщений хореографа в Logcat

Почему вы должны быть обеспокоены

Когда это сообщение появляется в эмуляторе Android и количество пропущенных кадров довольно мало (<100), вы можете сделать безопасную ставку медленного эмулятора – что происходит почти все время. Но если количество кадров пропущено и большое и порядка 300+, то с вашим кодом могут возникнуть серьезные проблемы. Устройства Android поставляются с огромным набором аппаратных средств, в отличие от устройств ios и windows. ОЗУ и центральный процессор меняются, и если вы хотите иметь разумную производительность и пользовательский интерфейс на всех устройствах, вам необходимо исправить это. Когда кадры пропускаются, пользовательский интерфейс медленный и медленный, что не является желательным для пользователя.

Как исправить это

Для этого требуется идентифицировать узлы, где есть или, возможно, может произойти длительная обработка. Лучший способ – сделать всю обработку независимо от того, насколько она маленькая или большая в потоке, отличном от основного потока пользовательского интерфейса. Так что будь доступ к форме данных SQLite Database или выполнению некоторых хардкорных математических упражнений или просто сортировке массива – сделайте это в другом потоке

Теперь здесь есть уловка. Вы создадите новый поток для выполнения этих операций, и когда вы запустите свое приложение, он столкнется с заявлением: «Только исходный поток, создавший иерархию представлений, может коснуться его представлений». Вам нужно знать, что пользовательский интерфейс в андроиде может быть изменен только основным потоком или потоком пользовательского интерфейса. Любой другой поток, который пытается это сделать, терпит неудачу и сбой этой ошибки. Что вам нужно сделать, так это создать новый Runnable внутри runOnUiThread, и внутри этой runnable вы должны выполнить все операции с пользовательским интерфейсом. Найдите пример здесь .

Итак, у нас есть Thread и Runnable для обработки данных из основного потока, что еще? В андроиде есть AsyncTask, который позволяет выполнять длительные процессы в потоке пользовательского интерфейса. Это наиболее полезно, когда приложения управляются данными или управляются веб-api или используют сложные пользовательские интерфейсы, такие как сборка с использованием Canvas. Сила AsyncTask заключается в том, что позволяет делать что-то в фоновом режиме, и как только вы закончите обработку, вы можете просто выполнить необходимые действия в пользовательском интерфейсе, не вызывая какого-либо замедляющего эффекта. Это возможно, потому что AsyncTask проистекает из потока пользовательского интерфейса Activity – все операции, которые вы выполняете в пользовательском интерфейсе через AsyncTask, выполняются, это другой поток из основного потока пользовательского интерфейса, отсутствие помех для взаимодействия с пользователем.

Итак, это то, что вам нужно знать для создания плавных приложений для Android, и насколько я знаю, каждый новичок получает это сообщение на своей консоли.

Я не пишу это, чтобы получить больше репутации. Я просто хочу поделиться тем, что произошло в моем случае. Как говорили другие, «Пропущенные 55 кадров!» Означает, что какая-то тяжелая обработка в вашем приложении. Для моего случая в моем приложении нет тяжелого процесса. Я дважды и тройной проверяю все и удаляю этот процесс, я думаю, немного тяжелый. Я удаляю фрагменты, действия, библиотеки, пока не останется только скелет. Но проблема все же не исчезла. Я решил проверить ресурсы и нашел некоторые значки, и фон, который я использую, довольно большой, поскольку я забыл проверить размер этих ресурсов.

Итак, мое предложение заключается в том, что если ни один из приведенных выше ответов не поможет, вы также можете проверить размер файлов ресурсов.

У меня тоже была такая же проблема.
Мой был случаем, когда я использовал фоновое изображение, которое было в drawables. Это конкретное изображение было около 130 кБ и использовалось во время экрана заставки и главной страницы моего приложения для Android.

Решение. Я просто переместил это конкретное изображение в папку drawables-xxx из drawables и смог освободить большую часть памяти, занятой в фоновом режиме, и пропущенные рамки больше не пропускали.

Обновление Используйте ресурсную папку «nodp» для хранения файлов обратных ссылок.
Будет ли приоритетная папка, пригодная для определения плотности, или drawable-nodpi?

Попытайтесь использовать следующие стратегии, чтобы улучшить производительность вашего приложения:

  • При необходимости используйте многопоточное программирование. Преимущества производительности огромны, даже если ваш смартфон имеет одно ядро ​​(потоки могут работать в разных ядрах, если процессор имеет два или более). Полезно сделать вашу логику приложения отделенной от пользовательского интерфейса. Используйте Java-потоки, AsyncTask или IntentService. Проверьте это .
  • Прочитайте и следуйте советам по разным характеристикам веб-сайта разработки Android. Проверьте здесь .

Другой распространенной причиной задержек в потоке пользовательского интерфейса является доступ SharedPreferences. Когда вы вызываете PreferenceManager.getSharedPreferences и другие подобные методы в первый раз, связанный .xml-файл сразу загружается и анализируется в том же потоке .

Одним из хороших способов борьбы с этой проблемой является запуск первой загрузки SharedPreference из фонового потока, начатой ​​как можно раньше (например, из onCreate вашего приложения). Таким образом, объект предпочтения может быть уже создан к тому моменту, когда вы захотите его использовать.

К сожалению, иногда чтение файлов предпочтений необходимо на ранних этапах запуска (например, в начальном Управлении или даже самом приложении). В таких случаях по-прежнему можно избежать срыва UI с помощью MessageQueue.IdleHandler . Сделайте все, что вам нужно для выполнения в основном потоке, а затем установите IdleHandler для выполнения кода, как только ваша активность будет полностью нарисована. В этом Runnable вы должны иметь доступ к SharedPreferences, не задерживая слишком много операций рисования и делая Хореографа несчастливым.

Я не эксперт, но я получил это отладочное сообщение, когда хотел отправить данные из приложения для Android на веб-сервер. Хотя я использовал класс AsyncTask и делал передачу данных в фоновом режиме, для получения данных результата с сервера я использовал метод get () класса AsyncTask, который делает синхронный пользовательский интерфейс, что означает, что ваш интерфейс будет слишком долго ждать. Поэтому мой совет заключается в том, чтобы ваше приложение выполняло все сетевые задачи в отдельном потоке.

У меня такая же проблема. В моем случае у меня было 2 вложенных Relative Layouts. RelativeLayout всегда должен выполнять два прохода. Если вы вложите RelativeLayouts, вы получите экспоненциальный алгоритм измерения.

Оптимизируйте свои изображения … Не используйте изображения размером более 100 КБ … Загрузка изображения занимает слишком много CPU и вызывает зависание вашего приложения.

У моего приложения была такая же проблема. Но он не делал ничего, кроме отображения на нем списка карточек и текста. Ничего не работает в фоновом режиме. Но затем после некоторого исследования выяснилось, что изображение, установленное для фона карты, вызывало это, хотя оно было небольшим (350kb). Затем я преобразовал изображение в 9patch изображений, используя http://romannurik.github.io/AndroidAssetStudio/index.html .
Это сработало для меня.

У меня возникла такая же проблема при разработке приложения, которое использует много доступных png-файлов в макете. Я также пытался оптимизировать свой код, насколько это возможно .. но это не сработало для меня .. Тогда я попытался уменьшить размер этих png .. и угадать, что он работает абсолютно нормально. Поэтому мое предложение – уменьшить Размер доступных ресурсов, если таковые имеются.

Вы можете использовать библиотеку Glide для загрузки изображений .. она будет загружать изображение в фоновый поток ..