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

Я установил последние версии SDK (API 16) и получил новейший ADT. Теперь я вижу эти сообщения в логарифме, что я совершенно уверен, чего я раньше не видел. Кто-нибудь имеет представление об этом?

06-29 23: 11: 17.796: I / Хореограф (691): пропущено 647 кадров! Приложение может делать слишком много работы над своей основной нитью.

Я сделал поиск и нашел эту ссылку: http://developer.android.com/reference/android/view/Choreographer.html . Это новый class, представленный в API 16.

Мне нужно знать, как я могу определить, что «слишком много работает» мое приложение может делать, поскольку вся моя обработка выполняется в AsyncTask s.

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

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

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

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

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

Я опаздываю на вечеринку, но, надеюсь, это полезное дополнение к другим ответам здесь …

Отвечая на вопрос / tl: dr;

Мне нужно знать, как я могу определить, что «слишком много работает» мое приложение может делать, поскольку вся моя обработка выполняется в AsyncTasks.

Ниже перечислены все кандидаты:

  • IO или дорогостоящая обработка основной нити (загрузочные чертежи, раздувание макетов и настройка Uri на ImageView все составляют IO на основной теме)
  • Рендеринг больших / сложных / глубоких иерархий
  • Недействительность больших частей иерархии View
  • Дорогостоящие методы onDraw в пользовательском View
  • Дорогие вычисления в анимации
  • Запуск «рабочих» streamов при слишком высоком приоритете, чтобы считаться «фоном» ( AsyncTask – это «фон» по умолчанию, java.lang.Thread нет )
  • Генерирование большого количества мусора, в результате чего сборщик мусора «остановит мир» – включая основной stream – пока он очищает

Чтобы определить конкретную причину, вам нужно будет профилировать свое приложение.

Более детально

Я пытался понять Хореографа, экспериментируя и смотря на код .

Документация Хореографа открывается с помощью «Координаты времени анимации, ввода и рисования». который на самом деле является хорошим описанием, но в остальном происходит чрезмерное подчеркивание анимации.

Хореограф фактически отвечает за выполнение трех типов обратных вызовов, которые выполняются в следующем порядке:

  1. обратные вызовы обработки ввода (обработка пользовательского ввода, такого как события касания)
  2. обратные вызовы анимации для анимации между кадрами, обеспечивая стабильное время начала кадра для всех / всех запущенных анимаций. Выполнение этих обратных вызовов 2-й означает, что любые вычисления, связанные с анимацией (например, изменение позиций View), уже были сделаны к тому моменту, когда вызывается третий тип обратного вызова …
  3. просмотреть обратные вызовы обхода для рисования иерархии представлений.

objective состоит в том, чтобы сопоставить скорость, с которой отменены недействительные просмотры (и анимация под напряжением) с помощью экрана vsync – обычно 60 кадров в секунду.

Предупреждение о пропущенных кадрах выглядит запоздалым: сообщение регистрируется, если один проход через 3 шага занимает более 30 раз ожидаемую продолжительность кадра, поэтому наименьшее число, которое вы можете ожидать в сообщениях журнала, «пропустит 30 кадров», ; Если каждый проход занимает 50% дольше, чем он должен пропустить 30 кадров ( озорной! ), Но вы не будете предупреждены об этом.

Из трех шагов было ясно, что это может быть не только анимация, которая может вызвать предупреждение: Недостаточно ли значительная часть большой иерархии View или View со сложным методом onDraw.

Например, это вызовет предупреждение несколько раз:

 public class AnnoyTheChoreographerActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_linear_layout); ViewGroup root = (ViewGroup) findViewById(R.id.root); root.addView(new TextView(this){ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); long sleep = (long)(Math.random() * 1000L); setText("" + sleep); try { Thread.sleep(sleep); } catch (Exception exc) {} } }); } } 

… который производит регистрацию следующим образом:

 11-06 09:35:15.865 13721-13721/example I/Choreographer﹕ Skipped 42 frames! The application may be doing too much work on its main thread. 11-06 09:35:17.395 13721-13721/example I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread. 11-06 09:35:18.030 13721-13721/example I/Choreographer﹕ Skipped 37 frames! The application may be doing too much work on its main thread. 

Вы можете видеть из стека во время onDraw что хореограф задействован независимо от того, оживляете ли вы:

на примере. AnnoyTheChoreographerActivity $ 1.onDraw (AnnoyTheChoreographerActivity.java:25) на android.view.View.draw (View.java:13759)

… довольно много повторений …

в android.view.ViewGroup.drawChild (ViewGroup.java:3169) в android.view.ViewGroup.dispatchDraw (ViewGroup.java3039) на android.view.View.draw (View.java:13762) в android.widget. FrameLayout.draw (FrameLayout.java:467) в com.android.internal.policy.impl.PhoneWindow $ DecorView.draw (PhoneWindow.java:2396) в android.view.View.getDisplayList (View.java:12710) на android .view.View.getDisplayList (View.java:12754) в android.view.HardwareRenderer $ GlRenderer.draw (HardwareRenderer.java:1144) в android.view.ViewRootImpl.draw (ViewRootImpl.java:2273) на android.view. ViewRootImpl.performDraw (ViewRootImpl.java:2145) в android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1956) в android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1112) в android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:4472) на android.view.Choreographer $ CallbackRecord.run (Хореограф.ява: 725) на android.view.Choreographer.doCallbacks (Хореограф.java: 555) на android.view.Choreographer.doFrame (Cho reographer.java:525) at android.view.Choreographer $ FrameDisplayEventReceiver.run (Хореограф.java:711) на android.os.Handler.handleCallback (Handler.java:615) на android.os.Handler.dispatchMessage (Handler.java : 92) at android.os.Looper.loop (Looper.java:137) в android.app.ActivityThread.main (ActivityThread.java:4898)

Наконец, если есть конкуренция с другими streamами, которые уменьшают объем работы, основной stream может быть выполнен, вероятность просканировать кадры резко возрастает, даже если вы фактически не выполняете работу над основным streamом.

В этой ситуации можно считать вводящим в заблуждение предположить, что приложение делает слишком много на основном streamе, но Android действительно хочет, чтобы рабочие streamи выполнялись с низким приоритетом, чтобы им не позволяли голодать основной stream. Если ваши рабочие streamи имеют низкий приоритет, единственный способ вызвать предупреждение Хореографа – это сделать слишком много для основного streamа.

Это сообщение Info, которое может появиться в вашем LogCat во многих ситуациях.

В моем случае это произошло, когда я раздувал несколько представлений из файлов макета XML программно. Сообщение само по себе безвредно, но может быть признаком более поздней проблемы, которая будет использовать всю оперативную память, которую может использовать ваше приложение, и заставить мега-злую силу Закрыть. Я вырос, чтобы быть тем разработчиком, который любит видеть его журнал WARN / INFO / ERROR Free. 😉

Итак, это мой собственный опыт:

Я получил сообщение:

 10-09 01:25:08.373: I/Choreographer(11134): Skipped XXX frames! The application may be doing too much work on its main thread. 

… когда я создавал свой собственный «суперкомплексный многосегментный список», раздувая представление из XML и заполняя его поля (изображения, текст и т. д.) данными, полученными от ответа REST / Веб-сервис JSON (без возможностей пейджинга) эти представления будут выступать в виде строк, заголовков подзаголовков и заголовков разделов, добавив все их в правильном порядке в LinearLayout (с вертикальной ориентацией внутри ScrollView). Все это для имитации listView с элементами, которые можно щелкнуть … но это еще один вопрос.

Как ответственный Разработчик, вы хотите сделать приложение действительно эффективным с системными ресурсами, поэтому наилучшая практика для списков (когда ваши списки не так сложны) заключается в использовании ListActivity или ListFragment с загрузчиком и заполнении ListView адаптером, это, по-видимому, более эффективно, на самом деле это так, и вы должны делать это все время, снова … если ваш список не настолько сложный.

Решение: я реализовал подкачку на моем веб-сервисе REST / JSON, чтобы предотвратить «большие размеры ответов», и я завернул код, который добавил заголовки «строки», «заголовки разделов» и «заголовки подсетей» на AsyncTask, чтобы сохранить главную Тема крутая.

Итак … Надеюсь, мой опыт помогает кому-то другому, который взламывает свои головы с помощью этого информационного сообщения.

Счастливый взлом!

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

В моем случае у меня есть эти сообщения, когда я показываю панель действия sherlock inderterminate progressbar. Поскольку это не моя библиотека, я решил скрыть результаты хореографа.

Вы можете скрыть выходы хореографа на представление Logcat, используя это выражение фильтра:

тег: ^ ((?! Хореограф). *) $

Я использовал регулярное выражение, объясненное в другом месте: Регулярное выражение для соответствия строке, которая не содержит слова?

  • открытая ссылка google play store в мобильной версии Android
  • Могу ли я хранить файлы изображений в firebase с помощью Java API
  • Android, как я могу получить список всех файлов в папке?
  • Android AlarmManager после перезагрузки
  • Не удалось выполнить синхронизацию проекта Gradle после того, как Google объявила о новой системе управления версиями sdk
  • Как запустить onListItemClick в Listactivity с помощью кнопок в списке?
  • Android map v2 zoom, чтобы показать все маркеры
  • Как сбросить Android Studio
  • как создать круговой просмотрщик?
  • ListView setOnItemClickListener не работает, добавив кнопку
  • Android - Можно ли отключить нажатие кнопки «Домой»
  • Давайте будем гением компьютера.