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

Ошибка Android "cpu может быть привязана"

Предисловие: эта серьезная ошибка может привести к блокировке устройств Android (неспособным нажать кнопки "Главная" / "Назад", требуется жесткий reset). Он связан с поверхностями OpenGL и воспроизведением звука. Logcat повторяет что-то с эффектом

W/SharedBufferStack( 398): waitForCondition(LockCondition) timed out (identity=9, status=0). CPU may be pegged. trying again.

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

Иногда я получаю эту ошибку при тестировании своего приложения на планшете Asus EEE Transformer. Сбой происходит, когда звуковая нить заполняет объекты MediaPlayer, используя MediaPlayer.create(context, R.raw.someid);, а поток GLSurface загружает текстуры из растровых изображений, используя

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.textureMap,opts);
gl.glGenTextures(1, texAtlas, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texAtlas[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();

Я не думаю, что причиной является звук, поскольку звук на самом деле все еще воспроизводится (поток, который загружает аудио, затем воспроизводит его через х раз). Если это так, причина заключается в буферизации OpenGL ES с использованием вышеуказанного кода.

Связанный материал

  • Этот SO сообщение относится к этой ошибке. Они используют OpenGL ES 2.0 и NDK. Я использую OpenGL ES 1.1 (хотя большинство устройств имитируют от 1.1 до 2.0, поэтому технически они используют 2.0), и я не использую NDK. Кроме того, они используют Android 2.1, и мой сбой происходит на Android 3.2.1.
  • Этот сайт связывает ошибку с объектом AudioTrack. Однако я не использую это в своем приложении.
  • Android Bug Tracker перечисляет это как известную ошибку, но пока еще нет решения (и это не исправлено в Honeycomb +).

Общие элементы

  • Замораживание происходит при буферизации. Вещь, которая буферизуется, обычно довольно велика, поэтому изображение (ошибка чаще встречается, чем больше изображение) или обычно звучит звук.
  • Замораживание происходит только на некоторых устройствах.
  • Замораживание не связано с конкретной версией Android - было записано, в частности, на 2.1 и 3.2.1.
  • Замораживание не связано с использованием NDK.
  • Замораживание не связано с одной практикой программирования (порядок буферизации, типы файлов и т.д.)

Мой вопрос довольно прост. Есть ли обходной путь для этой проблемы? Если вы не можете предотвратить это, есть ли способ провалиться изящно и предотвратить блокирование всего устройства?

4b9b3361

Ответ 1

В случае моей игры проблема "waitForCondition" была замечена в Samsung Galaxy S (Android 2.3.3). Конечно, я не знаю, была ли проблема обнаружена на разных устройствах, но, вероятно, проблема существует и там. К счастью, я смог воспроизвести его, поскольку один из моих друзей получил устройство, и он был достаточно любезен, чтобы одолжить мне одну неделю. В моем случае игра практически все написана на Java (несколько вызовов через NDK для функций OpenGL), поэтому я не уверен, что это применимо и к вашей проблеме.

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

ОБНОВЛЕНИЕ 1: В качестве дополнительной информации, я думаю, что я где-то читал, что у кого-то была такая же проблема с его процессором, и его решение заключалось в том, чтобы настроить все компоненты OpenGL Surface на 8 бит (альфа-компонент тоже), а не 565 или 4 бит (я точно не помню, в чем была неисправная конфигурация)

ОБНОВЛЕНИЕ 2: Также можно использовать следующую реализацию EGLConfigChooser: GdxEglConfigChooser.java. Если это не поможет в конечном итоге использовать подход, представленный в GLSurfaceView20.java.

ОБНОВЛЕНИЕ 3: Кроме того, упростить шейдеры программ, насколько это возможно, тоже помогло.

// in Activity...
glView = new GLSurfaceView(this);
glView.setEGLContextClientVersion(2); // OpenGL ES 2.0
//      glView.setEGLConfigChooser(false); // (1) false - no depth buffer
glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
glView.setEGLConfigChooser(8,8,8,8,0,0); // (2) TODO: crashes on devices which doesn't support this particular configuration
glView.setRenderer(new MyRenderer(this));

Ответ 2

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