0

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.

4

1 回答 1

0

我相信我解决了这个问题。我认为由于条件逻辑不正确,并非所有视图都被添加到 viewsToRemove ArrayList 中。

于 2012-09-26T17:09:25.267 回答