2014-02-03 1 views
0

Я делаю игру защиты башни, в которой я хотел бы разделить asyncTasks для обработки всех движений устройства, столкновений, повреждений и т. Д .; и я хочу, чтобы GL Thread обрабатывал только чертеж ...Android Opengl es 1 - asynctask вызывает странное поведение на некоторых устройствах

Итак, у меня есть три мои асинтеты в MyGLSurfaceView, расширяющие класс glSurfaceView.

Я обрабатываю onTouchEvents через переопределение в моем GLSurfaceView.

Все работает непосредственно на потоке GL, пока не настало время запуска мобов через лабиринт, на которых я использую последовательность обработчика h, проводя серию «подготовительных» методов, загружающих мобов для уровня, и готовя различные другие обязательные объекты. Последним шагом в этом процессе является редактирование sharedpreferences, которое в свою очередь запускает 3 asyncTasks (через реализацию onSharedPreferencesChangedListenner в MyGLSurfaceView (NOT my Renderer))

На моих старых устройствах (Nexus S и более ранней вкладке Samsung Galaxy) , это всегда работает отлично. На моей Galaxy S4 он работает только около 80-90% времени. Когда это не сработает, могут возникнуть различные альтернативные результаты. : - Приложение остается отзывчивым и продолжает рисовать все, что требуется на экране, минус все, что было изменено асинхронными; странно, используя Log, я заметил, что asynctasks также работает нормально, показывая ожидаемые значения в журнале (монстры двигаются правильно, по правильному пути, в то время как башни правильно стреляют по ним ракетами, и эти ракеты ведут себя как ожидалось (наносящий урон и потенциально вызывающий смерть толпы при ударе). Визуально я вижу скопление мобов на начальной точке пути, мои башни, мою игровую зону, мой пользовательский интерфейс (который остается полностью кликабельным и взаимодействующим с 0 задержками). Я заметил, что когда это поведение наблюдается, если я нажимаю домашний ключ для запуска onPause, а затем возвращаюсь в приложение, запуская onResume, действие возобновляется нормально, с самого начала (как будто все предыдущие записи журнала из моей асинтеты были потеряны). Это то, что обычно происходит, когда приложение терпит неудачу. Что может быть причиной этого? Мои асинхронные задачи иногда работают с отдельным экземпляром моего средства визуализации? k на старых устройствах, но не всегда на новом устройстве?

  • Приложение вылетает из-за нулевого указателя на моем массиве мобов (возможно, вещи выполняются не в порядке)?

Должен ли я избегать использования asynctask при использовании openGL es?

Должен ли я это делать? (обновление местоположений мобов через doInBackground и просто рисование объектов с их последними координатами (как определено в asynctask))

ответ

2

Не используйте для этого AsyncTasks. Существует несколько проблем, которые могут возникнуть:

  • AsyncTasks не гарантируется на исполнение в том порядке, в котором они были запущены.
  • Поведение изменилось со временем, поэтому ожидайте увидеть странные вещи на разных версиях платформы.
  • Существует ограниченное число AsyncTasks, которым разрешено работать в одно и то же время. Если вы начнете больше, они будут поставлены в очередь и только начнутся позже. И более разочаровывающе, это число изменилось между версиями api.

Эти пункты от docs могут быть интересны:

Порядок исполнения

Когда впервые, AsyncTasks были выполнены поочередно на одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи выполняются в одном потоке, чтобы избежать ошибок обычного приложения, вызванных параллельным выполнением.

Если вы действительно хотите выполнить параллельное выполнение, вы можете вызвать executeOnExecutor (java.util.concurrent.Executor, Object []) с помощью THREAD_POOL_EXECUTOR.

общественности окончательное AsyncTask executeOnExecutor ...

Предупреждение: Разрешение нескольких задач параллельной работы из пула потоков, как правило, не то, что хочет, потому что порядок их работы не определен. Например, если эти задачи используются для изменения общего состояния (например, для записи файла из-за нажатия кнопки), нет никаких гарантий в отношении порядка модификаций. Без тщательной работы в редких случаях, когда более новая версия данных может быть переписана более старой версией, что приводит к неясным проблемам потери данных и стабильности. Такие изменения лучше всего выполнять в серийном режиме; чтобы гарантировать, что такая работа сериализована независимо от версии платформы, вы можете использовать эту функцию с SERIAL_EXECUTOR.

Смежные вопросы