I have a custom ViewGroup
that contains about 10 SurfaceView
's. When you push a button a xml file gets parsed and a skin gets generated which contains 10 more surface views. These then get added to the view group, the view group gets invalidated, and the previous 10 surfaceviews get removed by viewgroup.removeView
. This is to avoid flickering. It all works great but after doing it maybe 8 times I begin to run out of memory and lockCanvas
returns null on the new surfaceviews. Is removeView
, and setting all references to the surface view to null all you need to release a surface? Here is what the code looks like that removes the view:
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();
}
}
});
}
This block of code gets run in onDraw
after the new SurfaceView
's get painted (to avoid flickering). I've tried experimenting with garbage collection and also with manually calling the SurfaceView
's finalize method which is what the v.cleanup
call does but still runs out of memory after a while. It seems to work on Android 4.0 but not on <= 2.3.x.
Here are the errors adb shows:
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)
Any help would be greatly appreciated.