1

好吧,我有一个绝对让我困惑的问题。我有一个动态壁纸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}
4

0 回答 0