неожиданный системный вызов Android делает плавное отображение прокрутки графического заикания - PullRequest
3 голосов
/ 01 декабря 2011

В настоящее время я пишу приложение, которое должно отображать кривую измерения в режиме реального времени в режиме прокрутки (например, регистратор ЭКГ или осциллограф).Неожиданный системный вызов в UI-Thread заставляет дисплей заикаться.

Данные поступают через Bluetooth.Все работает нормально, и дисплей довольно плавно прокручивается со средней скоростью обновления 26 кадров / с.Но, тем не менее, дисплей замечательно заикается.

Я использовал traceview, чтобы получить больше информации, и в соответствии с traceview заикание является результатом вызова android/view/ViewRoot.handleMessage, который в среднем длится 131 мс на вызов.Если я продолжу копать в трассировке, циклы сгорят внутри android/view/ViewRoot.performTraversals.92% этих циклов ЦП расходуются в основном на рекурсивные вызовы android/view/View.measure.

Оттуда это усложняется из-за структуры рекурсивного вызова.Но я могу найти вызовы метода onMeasure () LinearLayout, FrameLayout и RelativeLayout.Метод onMeasure () каждого типа Layout потребляет примерно одинаковое количество циклов ЦП.Что очень странно, поскольку в своей деятельности я использую только простую LinearLayout с двумя элементами.Я просто не вижу причин, по которым предполагаемая перекомпоновка LinearLayout с 2-мя элементами выполняет вызовы к неиспользуемым макетам и занимает колоссальные 131 мс для этого.

Дополнительная информация:

  • Платформа HTC desire HD с Android 2.3.1.
  • Я использую обработчик для выполнения рисования в потоке пользовательского интерфейса.
  • Макет представляет собой простой LinearLayout с 2 элементами: пользовательскийview и textField.
  • Строка состояния скрыта с getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);.
  • Рисование выполняется для каждого нового блока данных, который прибывает ок.каждые 50 мсек.
  • Сам рисунок использует холст и обладает достаточной производительностью, чтобы не отставать от поступающих данных.

После этого длинного объяснения возникают вопросы:

  1. Что вызывает андроид / view / ViewRoot.handleMessage?(вызовы относительно равномерно распределены каждые 850 мс и не имеют явной связи (никакие прямые вызовы, количество вызовов и относительные позиции не связаны с обработчиком сообщений для рисования) с какой-либо деятельностью моей Деятельности)
  2. Какможно ли подавить вызовы в android / view / ViewRoot.handleMessage или как я могу сделать их быстрее (в моем LinearLayout всего 2 элемента)
  3. вызовы в неиспользуемые макеты сначала заставили меня задуматься о строке состояния илинекоторые скрытые действия (например, домашний экран), которые могут использовать такие макеты.Но почему эти звонки являются частью следа моей деятельности?Насколько я понимаю, след должен только отслеживать активный процесс.например, вызовы моей службы, которая производит данные в реальном времени, не являются частью трассировки.
  4. Есть ли возможность отслеживать отдельные вызовы некоторых компонентов системы?При увеличении масштаба в режиме просмотра я вижу следующую последовательность вызовов: toplevel -> android/os/Message.clearForRecycle() -> android/os/MessageQueue.nativePollOnce() -> android/os/SystemClock.uptimeMillis() -> com/htc/profileflag/ProfileConfig.getProfilePerformance() -> android/os/Handler.dispatchMessage() -> android/view/ViewRoot.performTraversals()
  5. Не по теме: есть ли возможность экспортировать данные, которые отображаются внутри traceview (время родителей-детей-ЦП и т. Д.), Кромескриншот?

1 Ответ

5 голосов
/ 13 декабря 2011

Хорошо, я нашел причину для длинного звонка на android/view/ViewRoot.handleMessage.Это действительно было вызвано моим приложением.

Мое приложение имеет 2 экрана («Действия»), один со сложным макетом для информации о состоянии, а другой - отображение входящих данных в реальном времени., который приходит через Bluetooth содержит смешанные данные в реальном времени и данные о состоянии.Когда я переключался в режим реального времени, я прекращал статус «Активность» с помощью finish(); после запуска нового действия в реальном времени.К сожалению, этого недостаточно, чтобы остановить также обработчик сообщений, который получает новую информацию о состоянии в потоке пользовательского интерфейса и продолжает обновлять данные о состоянии в невидимой и завершенной операции.Ретрансляция этого действия вызвала заикание данных в реальном времени.

Теперь эта проблема решена.Прокрутка дисплея теперь достаточно плавная.

Спасибо за ваше терпение.Может быть, это будет полезно всем, кто спотыкается в этом потоке на stackoverflow.

jepo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...