Android 安卓;cpu可能被钉住;缺陷

Android 安卓;cpu可能被钉住;缺陷,android,opengl-es,Android,Opengl Es,前言:这个严重的错误会导致Android设备锁定(无法按下Home/Back按钮,需要硬重置)。它与OpenGL曲面和音频播放相关联。Logcat重复了一些类似于 每秒一次,因此该错误的名称。造成这种情况的根本原因可能是缓冲数据(无论是声音还是图形)时出现死锁 在华硕EEE Transformer平板电脑上测试我的应用程序时,我偶尔会遇到这个错误。声音线程使用MediaPlayer.create(context,R.raw.someid)填充MediaPlayer对象时发生崩溃和GLSurfac

前言:这个严重的错误会导致Android设备锁定(无法按下Home/Back按钮,需要硬重置)。它与OpenGL曲面和音频播放相关联。Logcat重复了一些类似于

每秒一次,因此该错误的名称。造成这种情况的根本原因可能是缓冲数据(无论是声音还是图形)时出现死锁

在华硕EEE Transformer平板电脑上测试我的应用程序时,我偶尔会遇到这个错误。声音线程使用
MediaPlayer.create(context,R.raw.someid)填充
MediaPlayer
对象时发生崩溃
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();
我不认为原因是音频,因为音频实际上仍在播放(加载音频的线程在x时间后播放)。如果是这样,原因在于使用上述代码的OpenGL ES缓冲

相关材料

  • 指的是这个bug。他们使用OpenGLES2.0和NDK。我使用OpenGL ES 1.1(尽管大多数设备模拟1.1到2.0,所以技术上他们使用2.0),我不使用NDK。此外,他们使用安卓2.1,我的崩溃发生在安卓3.2.1上
  • 将bug链接到
    AudioTrack
    对象。但是,我在我的应用程序中不使用它
  • 将此列为已知的bug,但到目前为止还没有解决方案(而且它在Honeycomb+中还没有修复)
常用元素

  • 缓冲时发生冻结。缓冲的对象通常很大,因此图像(图像越大,错误发生的频率越高)或音频通常会受到影响
  • 冻结仅在某些设备上发生
  • 冻结与特定的Android版本无关——在2.1和3.2.1等版本中都有记录
  • 冻结与NDK的使用无关
  • 冻结与单个编程实践(缓冲顺序、文件类型等)无关

我的问题很简单。这个问题有解决办法吗?如果你不能阻止它,有没有办法优雅地失败并防止整个设备被阻塞

增加设备的虚拟内存可以降低发生此问题的次数。当然,这不是一个选项,除非您是该设备的制造商

在我的游戏中,三星Galaxy S(Android 2.3.3)上出现了“waitForCondition”问题。当然,我不知道在不同的设备上是否注意到了这个问题,但问题可能也存在。幸运的是,当我的一个朋友得到这个设备时,我能够复制它,他好心地借给了我一个星期。 在我的例子中,游戏几乎都是用Java编写的(很少通过NDK调用OpenGL函数),所以我不确定这是否也适用于您的问题。

无论如何,这个问题似乎与OpenGL内部缓冲区有关。在下面显示的代码中,注释掉的行(1)已更改为(2)-手动配置选择。我还没有彻底测试它,但自从那次更改之后,我没有注意到任何冻结,因此有希望..

更新1:作为补充信息,我想我在某个地方读到,有人的CPU也有同样的问题,他的解决方案是将所有OpenGL表面组件设置为8位(alpha组件也是),而不是565或4位(我不记得错误的配置是什么)

更新2:也可以考虑使用EgListCopisher:如果这无助于最终使用。

更新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));

“Bricked”指的是无法启动的设备,而不是在重新启动之前冻结的设备。FWIW,我很少遇到这个问题。它不会导致冻结,只会导致缓慢,可能是由于超时解决了死锁。我没有直接使用OpenGL,但我有一个PriorityBlockingQueue,它在工作线程上运行,并且经常被UI线程中断。当它被中断时,它会在退出之前将当前正在处理的项添加回队列,这可能是造成死锁的原因。这可能是我自己的错误,但它会导致相同的消息,因此,当这种情况发生时,OpenGL内部可能会发生类似的情况。这对最终用户不可用。仅适用于制造商
// 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));