OpenGL动态壁纸仅在三星手机上崩溃(最值得一提的是三星Galaxy s3)

时间:2012-12-20 02:33:13

标签: android live-wallpaper wallpaper samsung-mobile

嗯,我有一个绝对令我困惑的问题。我有一个动态壁纸https://play.google.com/store/apps/details?id=com.simpleworkerz.boise.sunsets#?t=W251bGwsMSwyLDIxMiwiY29tLnNpbXBsZXdvcmtlcnouYm9pc2Uuc3Vuc2V0cyJd

该应用程序包含动态壁纸和幻灯片放映。幻灯片版本与三星完美配合(动态壁纸和幻灯片向我们展示了相同的opengl渲染器,但当用户进入动态壁纸并选择“SET WALLPAPER”时,会发生以下情况。

1)设置的壁纸文字会改变颜色。 (尽管仍然没有启动) 2)屏幕再次变黑并显示消息“正在加载壁纸” 3)3-4秒后没有任何内容出现,并且有消息称Boise Sunsets已停止工作并需要关闭。或者点击“第二次设置壁纸会导致力量关闭。

在用户点击“设置壁纸”之前,一切正常,所以一切都在渲染和显示。

所以我假设我的问题与oncreate或onsurface有关。当点击“设置壁纸”按钮时,我不太明白究竟是什么叫做。有人知道吗?

这是我的壁纸代码。

import android.content.SharedPreferences;
import android.service.wallpaper.*;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;

 public class BoiseSunsetsLiveWallpaper extends WallpaperService{

@Override
public Engine onCreateEngine(){

    return new MyEngine();

}

class MyEngine extends Engine
{

    private float mTouchX = -1;
    private float mTouchY = -1;

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

    private ExecutorService executor;
    private Runnable drawCommand;

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

        executor = Executors.newSingleThreadExecutor();

        drawCommand = new Runnable(){
            public void run(){

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

    }

    @Override
    public void onDestroy(){
        executor.shutdown();

        //setTouchEventsEnabled(false);
        //glRenderer.onSurfaceDestroyed();
        glRenderer = null;

        super.onDestroy();
    }

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


        Runnable surfaceCreatedCommand = new Runnable(){
            public void run(){

                //Initialize Open GL
                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, EGL10.EGL_DONT_CARE,
                        EGL10.EGL_GREEN_SIZE, EGL10.EGL_DONT_CARE,
                        EGL10.EGL_BLUE_SIZE, EGL10.EGL_DONT_CARE,
                        EGL10.EGL_DEPTH_SIZE, EGL10.EGL_DONT_CARE,
                        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(BoiseSunsetsLiveWallpaper.this);
                glRenderer.onSurfaceCreated(gl, config);
                }
            };
            executor.execute(surfaceCreatedCommand);

    }

    @Override
    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);
    }

    @Override
    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);
    }

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

        if(visible){

            executor.execute(drawCommand);
        }
    }

    @Override
    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 (xOffsetStep != 0f){
                    glRenderer.setParallax(xOffset - 0.5f);
                }
            }
        };
        executor.execute(offsetsChangedCommand);
    }

    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {


    }

    @Override
    public void onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            mTouchX = event.getX();
            mTouchY = event.getY();
        } else {
            mTouchX = -1;
            mTouchY = -1;
        }

        Runnable TouchChangedCommand = new Runnable(){
            public void run(){
                if (mTouchX >=0 && mTouchY >= 0){

                    glRenderer.IsPressed(mTouchX, mTouchY);


                }
                else{


                }
            }
        };
        executor.execute(TouchChangedCommand);

        super.onTouchEvent(event);
    }

}

}

奇怪的是,如果我真的很快点击设置壁纸并快速退出屏幕有时壁纸实际上会工作!或者几秒钟后会关闭。

当我在Verizon和Sprint商店测试时,我实际上并没有拥有三星手机。大声笑。所以我不能给出具体的错误。一旦我拿到三星测试手机,我会的。在那之前,我很感激你能够集思广益的任何见解!

我正在使用来自Hello,Android的Ed Burnette代码的一部分用于动态壁纸。我以为我的问题与这个问题有关。 http://forums.pragprog.com/forums/152/topics/8254 但是我做了所有这些改变,但仍然遇到了问题。

更新

/AndroidRuntime( 9520): FATAL EXCEPTION: pool-1-thread-1

E/AndroidRuntime( 9520): java.lang.NullPointerException

E/AndroidRuntime( 9520):    at com.simpleworkerz.boise.sunsets.BoiseSunsetsLiveWallpaper$MyEngine$1.run(BoiseSunsetsLiveWallpaper.java:55)

E/AndroidRuntime( 9520):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)

E/AndroidRuntime( 9520):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)

E/AndroidRuntime( 9520):    at java.lang.Thread.run(Thread.java:856)

D/KeyguardViewMediator(  651): setHidden false

D/KeyguardViewMediator(  651): setHidden false

I/WindowManager(  651): WIN DEATH: Window{423d0120 XXX.XXXXX.XXX.XXXXXXX/XXX.XXXXX.XXX.XXXXXXX.XXXXXXXX.XXXXXXXXXXXX paused=false}

0 个答案:

没有答案