lockCanvas () очень медленно - PullRequest
       14

lockCanvas () очень медленно

14 голосов
/ 24 февраля 2011

Тестирование моей игры на более медленном устройстве (Orange San Francisco aka ZTE Blade), и я получаю ужасающую частоту кадров.

Я поместил некоторый отладочный код в цикл отрисовки и обнаружил, что следующая строка принимаетсвыше 100 мс:

c = mSurfaceHolder.lockCanvas();

Кто-нибудь еще видел такое поведение?Я временно заменил SurfaceView, расширив View и реализовав onDraw (), и получил намного лучшую частоту кадров.

Хотя в целом SurfaceView намного быстрее в моем HTC Desire.Я подозреваю, что это может быть проблема Android 2.1.Я обдумываю возможность рутирования телефона и обновления его до 2.2, если это возможно, но я действительно хотел, чтобы устройство работало на 2.1, чтобы в долгосрочной перспективе это могло привести к обратным результатам.

** обновление **

Я работал над этим еще немного и обнаружил еще несколько загадочных аспектов.

Я рутировал телефон и установил 2.2, и проблема все еще возникает.При первом запуске приложения lockCanvas работает как положено (0-1 мс).Затем в какой-то момент во время моей инициализации lockCanvas внезапно начинает принимать около 100 мс.

Возможно, стоит указать, что я загружаю свои активы в асинхронной задаче, чтобы я мог отобразить экран загрузки.

Несмотря на все мои усилия, чтобы определить, что на самом деле делает программа, когда происходит медлительность, я не смог этого сделать.Фактически, когда я запускаю его в режиме отладки и в один шаг, он работает быстро!

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

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

Я в значительной степени нахожусь в конце своей привязи по этой глупой нелогичной проблеме!У меня есть разум, чтобы отнести это к конкретной проблеме устройства.

Я чувствую, что это может быть связано с использованием памяти.Может быть, что-то поменяется местами, и это влияет на видео-плейер?

По крайней мере, меня интересуют теории.

Ответы [ 4 ]

11 голосов
/ 10 марта 2011

О lockCanvas () из документов:

Если вы вызываете это несколько раз, когда Поверхность не готова (до Callback.surfaceCreated или после Callback.surfaceDestroyed), ваши звонки будет замедлен до медленной скорости в Чтобы избежать использования процессора.

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

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

0 голосов
/ 28 декабря 2015

Я столкнулся с той же загадочной проблемой с Canvas рисованием, но решил ее, изменив Canvas рисунок на рисунок SurfaceView.Но сейчас у меня постоянно медленный lockCanvas() звонок.Вот мои результаты наблюдения.Проблема присутствует только на некоторых устройствах:

  • Galaxy Note 3 n900: есть проблемы
  • Galaxy Note 3 n9005: есть проблемы
  • Galaxy S4 i9505: есть проблемы
  • Galaxy Gio: нет проблем
  • LG G2 D802: есть проблемы
  • Galaxy S2 i9100: нет проблем

Я временно заменилSurfaceView, расширив View и реализовав onDraw (), и я получил гораздо лучшую частоту кадров

. Я также заметил, что телефоны Samsung используют GLES20Canvas вместо обычных Canvas с onDraw() рисованием, так какрезультат - лучшая производительность.

0 голосов
/ 22 июня 2013

Недавно я обнаружил, что если для рисования на холсте используются большие растровые изображения и , эти растровые изображения хранятся в классе действия - сама команда "_surfaceHolder.lockCanvas ()" занимает очень много времени (около 70 мс в зависимости от устройства). ОДНАКО, перемещение этого растрового хранилища в другой класс (в другом файле, скажем, MY_DATA), и действие имеет только ссылку на этот новый класс - решает проблему.

У меня нет объяснения этому явлению.

0 голосов
/ 06 декабря 2011

Итак, может быть, мы могли бы использовать holder.isCreating () для проверки состояния? этот метод вернет true, если холст все еще создается.

что-то вроде while (holder.isCreating ()) {} может = holder.lockCanvas ();

Но я немного запутался. Как я знаю, Колбек вызывается, когда создается вид с поверхности. Мы должны реализовать интерфейс SurfaceHolder.Callback. И когда на поверхности создается метод обратного вызова public void surfaceCreated (держатель SurfaceHolder) {} будет вызван. Из метода SurfaceCreated я запускаю нить gameloop.

...