Android:Surface已发布

时间:2017-08-14 13:30:00

标签: android surfaceview

所以这段代码似乎是问题所在:

public void surfaceCreated(final SurfaceHolder sh) {
    loop = new Loop();
    loop.setMethod(new LoopMethod() {
        public void callMethod() {
            Canvas canvas = sh.lockCanvas();
            synchronized(sh) {
                draw(canvas);
            }
            sh.unlockCanvasAndPost(canvas);
        }
    });
    loop.setRunning(true);
    loop.start();
}

这样可以正常工作,直到用户退出应用程序,或打开“最近的项目”托盘。我得到以下错误:

java.lang.IllegalStateException: Surface has already been released.

指向这一行:

 sh.unlockCanvasAndPost(canvas);

为什么会发生这种情况?如何解决?

编辑:整个问题类

public class SplashScreen extends SurfaceView implements SurfaceHolder.Callback {
    private SplashActivity splashActivity;
    private Loop loop;

    //Loading gif info
    private Movie loadingGif;
    private long gifStart;
    private int gifW, gifH;
    private boolean gifDone;

    public SplashScreen(Context context, SplashActivity splashActivity) {
        super(context);
        getHolder().addCallback(this);

        this.splashActivity = splashActivity;

        //Load gif in
        InputStream gifStream = context.getResources().openRawResource(+ R.drawable.load);
        loadingGif = Movie.decodeStream(gifStream);
        gifW = loadingGif.width();
        gifH = loadingGif.height();
        gifDone = false;
    }

    private void beginLoading() {

    }

    public void surfaceCreated(final SurfaceHolder sh) {
        loop = new Loop();
        loop.setMethod(new LoopMethod() {
            public void callMethod() {
                Canvas canvas = sh.lockCanvas();
                synchronized(sh) {
                    draw(canvas);
                }
                sh.unlockCanvasAndPost(canvas);
            }
        });
        loop.setRunning(true);
        loop.start();
    }

    public void draw(Canvas canvas) {
        if(canvas != null) {
            super.draw(canvas);
            canvas.save();

            canvas.drawColor(Color.rgb(69, 69, 69));
            Paint p = new Paint();
            p.setAntiAlias(true);

            long now = android.os.SystemClock.uptimeMillis();
            if(gifStart == 0)
                gifStart = now;
            if(loadingGif != null) {
                int dur = loadingGif.duration();
                if(!gifDone) {
                    int relTime = (int) ((now - gifStart) % dur);
                    loadingGif.setTime(relTime);
                }
                else
                    loadingGif.setTime(dur);

                if(now - gifStart > dur && !gifDone) {
                    gifDone = true;
                    loadingGif.setTime(dur);
                    beginLoading();
                }

                float scaleX = getWidth()/gifW*1f;
                float scaleY = getHeight()/gifH*1f;
                float centerX = getWidth()/2/scaleX - gifW/2;
                float centerY = getHeight()/2/scaleY - gifH/2;

                canvas.scale(scaleX, scaleY);
                loadingGif.draw(canvas, centerX, centerY, p);
                canvas.restore();

                p.setColor(Color.WHITE);
                p.setTypeface(Typeface.create("Segoe UI", Typeface.BOLD));
                p.setTextSize(UsefulMethods.spToPx(12));
                String s = "Version " + BuildConfig.VERSION_NAME;
                canvas.drawText(s, 10, getHeight() - 10, p);
            }
        }
        else
            System.out.println("not drawing :(");
    }

    public void surfaceDestroyed(SurfaceHolder sh) {
        loop.setRunning(false);
    }
    public void surfaceChanged(SurfaceHolder sh, int format, int width, int height) {
        System.out.println("call");
    }
}

1 个答案:

答案 0 :(得分:2)

检查可见性是否已更改,是否有暂停/恢复循环:

public void onVisibilityChanged(View view, int visibility) {
    super.onVisibilityChanged(view, visibility);
    if(loop != null)
        if(visibility == VISIBLE)
            if(!loop.isRunning())
                loop.setRunning(true);
            else;
        else if(visibility == INVISIBLE)
            if(loop.isRunning())
                loop.setRunning(false);
}