我有一个自定义ViewGroup
,其中包含大约10 SurfaceView
个。按下按钮时,将解析xml文件并生成包含10个以上表面视图的外观。然后,这些会被添加到视图组,视图组将失效,之前的10个表面视图将被viewgroup.removeView
删除。这是为了避免闪烁。这一切都很好但是在做了8次之后我开始耗尽内存并且lockCanvas
在新的表面视图上返回null。是removeView
,并将表面视图的所有引用设置为null以释放曲面所需的全部内容吗?以下是删除视图的代码:
if (viewsToRemove.isEmpty() == false) {
this.post( new Runnable()
{
public void run() {
if (viewsToRemove.isEmpty() == false) {
for (IView v : viewsToRemove) {
SurfaceView sv = (SurfaceView)v;
removeView(sv);
v.cleanup();
}
viewsToRemove.clear();
System.gc();
invalidate();
}
}
});
}
这个代码块在新的onDraw
被绘制后在SurfaceView
中运行(以避免闪烁)。我已经尝试过使用垃圾收集进行实验,也尝试手动调用SurfaceView
的finalize方法,这是v.cleanup
调用的方法,但一段时间后仍会耗尽内存。它似乎适用于Android 4.0,但不适用于< = 2.3.x。
以下是adb显示的错误:
09-25 14:51:01.419: E/Surface(4131): Surface (identity=17237) requestBuffer(1, 0, 0, 1, 00000203) returned a buffer with a null handle
09-25 14:51:01.419: E/Surface(4131): getBufferLocked(1, 0, 0, 1, 00000203) failed (Out of memory)
09-25 14:51:01.419: E/Adreno200-EGL(4131): egliSwapWindowSurface: unable to dequeue native buffer
09-25 14:51:01.469: E/Surface(4131): Surface (identity=17237) requestBuffer(1, 0, 0, 1, 00000203) returned a buffer with a null handle
09-25 14:51:01.469: E/Surface(4131): getBufferLocked(1, 0, 0, 1, 00000203) failed (Out of memory)
09-25 14:51:01.469: E/Adreno200-EGL(4131): eglLockWindowSurface: unable to dequeue native buffer
09-25 14:51:01.549: E/AndroidRuntime(4131): FATAL EXCEPTION: GLThread 25
09-25 14:51:01.549: E/AndroidRuntime(4131): java.lang.RuntimeException: eglSwapBuffers failed: EGL_BAD_ALLOC
09-25 14:51:01.549: E/AndroidRuntime(4131): at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1080)
09-25 14:51:01.549: E/AndroidRuntime(4131): at android.opengl.GLSurfaceView$EglHelper.swap(GLSurfaceView.java:1038)
09-25 14:51:01.549: E/AndroidRuntime(4131): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1364)
09-25 14:51:01.549: E/AndroidRuntime(4131): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)
非常感谢任何帮助。
答案 0 :(得分:0)
我相信我解决了这个问题。我认为由于条件逻辑不正确,并不是所有的视图都被添加到viewsToRemove ArrayList中。