Eclipse for Android app中的执行程序服务问题

时间:2011-09-13 18:11:55

标签: android eclipse opengl-es wallpaper executor

基本上,我正在为Android手机开发OpenGL动态壁纸。这是我的壁纸服务类。

public class Wallpaper extends GLWallpaperService {

private class MyEngine extends Engine {

    private GLRenderer glRenderer;
    private GL10 gl;
    private EGL10 egl;
    private EGLContext glc;
    private EGLDisplay glDisplay;
    private EGLSurface glSurface;

    private ExecutorService executor;
    private Runnable drawCommand;

    public void onCreate(final SurfaceHolder holder) {
        super.onCreate(holder);


        executor = Executors.newScheduledThreadPool(BIND_AUTO_CREATE);

        drawCommand = new Runnable() {
            public void run() {
                glRenderer.onDrawFrame(gl);
                egl.eglSwapBuffers(glDisplay, glSurface);
                if (isVisible()
                        && egl.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
                    executor.execute(drawCommand);
                }
            }
        };

    }

    public void onSurfaceCreated(final SurfaceHolder holder) {
        super.onSurfaceCreated(holder);

        Runnable surfaceCreatedCommand = new Runnable() {
            public void run() {
                // Initialize OpenGL
                egl = (EGL10) EGLContext.getEGL();
                glDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
                int[] version = new int[2];
                egl.eglInitialize(glDisplay, version);
                int[] configSpec = { EGL10.EGL_RED_SIZE, 5,
                        EGL10.EGL_GREEN_SIZE, 6, EGL10.EGL_BLUE_SIZE, 5,
                        EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
                EGLConfig[] configs = new EGLConfig[1];
                int[] numConfig = new int[1];
                egl.eglChooseConfig(glDisplay, configSpec, configs, 1,
                        numConfig);
                EGLConfig config = configs[0];

                glc = egl.eglCreateContext(glDisplay, config,
                        EGL10.EGL_NO_CONTEXT, null);

                glSurface = egl.eglCreateWindowSurface(glDisplay, config,
                        holder, null);
                egl.eglMakeCurrent(glDisplay, glSurface, glSurface, glc);
                gl = (GL10) (glc.getGL());

                // Initialize Renderer
                glRenderer = new GLRenderer(Wallpaper.this);
                glRenderer.onSurfaceCreated(gl, config);
            }
        };
        executor.execute(surfaceCreatedCommand);

    }


    public void onSurfaceDestroyed(final SurfaceHolder holder) {

        Runnable surfaceDestroyedCommand = new Runnable() {
            public void run() {
                // Free OpenGL resources
                egl.eglMakeCurrent(glDisplay, EGL10.EGL_NO_SURFACE,
                        EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
                egl.eglDestroySurface(glDisplay, glSurface);
                egl.eglDestroyContext(glDisplay, glc);
                egl.eglTerminate(glDisplay);

            }
        };
        executor.execute(surfaceDestroyedCommand);

        super.onSurfaceDestroyed(holder);
    }


    public void onSurfaceChanged(final SurfaceHolder holder,
            final int format, final int width, final int height) {
        super.onSurfaceChanged(holder, format, width, height);

        Runnable surfaceChangedCommand = new Runnable() {
            public void run() {
                glRenderer.onSurfaceChanged(gl, width, height);
            }
        };
        executor.execute(surfaceChangedCommand);

    }

    public void onDestroy() {

        executor.shutdownNow();

        super.onDestroy();
    }


    public void onVisibilityChanged(final boolean visible) {
        super.onVisibilityChanged(visible);

        if (visible) {
            executor.execute(drawCommand);
        }

    }


    public void onOffsetsChanged(final float xOffset, final float yOffset,
            final float xOffsetStep, final float yOffsetStep,
            final int xPixelOffset, final int yPixelOffset) {
        super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
                xPixelOffset, yPixelOffset);

        Runnable offsetsChangedCommand = new Runnable() {
            public void run() {
                if (1 / xOffsetStep + 1 != 0f) {
                    glRenderer.setParallax(xOffset - 1f);
                }
            }
        };
        executor.execute(offsetsChangedCommand);

    }

}


public Engine onCreateEngine() {
    return new MyEngine();
}

}

它完全适用于我的手机(三星Galaxy S2)和其他几款手机,但有报道称它不会加载。即使从Galaxy S1型号也无法预览动态壁纸!由于这可以在我的手机上工作,我无法弄清楚它有什么问题。我没有那些无法运行该程序的手机,所以我无法解决问题。


回答是这样的。但我使用的是OpenGL ES 1.0,你可以看到EGL10 ......导入的GL10。哦,但我看到我确实导入了一个GL11(OpenGL 1.1),这可能导致了我想的问题?

2 个答案:

答案 0 :(得分:0)

Android 2.2及更高版本支持OpenGL ES 2.0。

三星Galaxy S1和目前可用的许多其他手机的运行时间早于2.2。

我建议您仔细检查您的API级别,并考虑回滚到OpenGL ES 1.0或编写包装器以将其用于不同的API级别。

答案 1 :(得分:0)

尝试从executor.shutdownNow();删除onDestroy()。 一些三星手机有过早调用onDestroy的倾向,这将关闭线程。