Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

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

  • IO или дорогостоящая обработка основной резьбы (загрузочные чертежи, раздувание макетов и настройка Uri на ImageView все составляют IO в основном потоке)
  • Оказание иерархии больших/сложных/глубоких View
  • Недействительность больших частей иерархии View
  • Дорогостоящие методы onDraw в пользовательских View 's
  • Дорогостоящие вычисления в анимации
  • Запуск "рабочих" потоков при слишком высоком приоритете, который будет считаться "фоном" (AsyncTask по умолчанию "фон", java.lang.Thread нет)
  • Создание много мусора, в результате чего сборщик мусора "остановит мир" - включая основной поток - пока он очищает

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

Подробнее

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

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

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

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

Цель состоит в том, чтобы сопоставить скорость, с которой недействительные представления перерисовываются (и анимация под напряжением) с помощью экрана 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.java:3039) на android.view.View.draw(View.java:13762) в android.widget.FrameLayout.draw(FrameLayout.java:467) at 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) at 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) at android.view.ViewRootImpl $TraversalRunnable.run(ViewRootImpl.java:4472) на android.view.Choreographer $CallbackRecord.run(Хореограф.ява: 725) на android.view.Choreographer.doCallbacks(Хореограф .java:555) на android.view.Choreographer.doFrame(Хореограф .java:525) на android.view.Choreographer $FrameDisplayEventReceiver.run(Хореограф .java:711)на android.os.Handler.handleCallback(Handler.java:615) на android.os.Handler.dispatchMessage(Handler.java:92) на android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4898)

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

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

Ответ 3

Это сообщение 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, чтобы держите главную тему прохладной.

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

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

Ответ 4

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

Ответ 5

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

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

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

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