2017-08-14 6 views
1

Also das Stück Code, scheint das Problem zu sein:Android: Oberfläche wurde veröffentlicht

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(); 
} 

Dies, bis der Benutzer Geldstrafe bis arbeitet sichert aus der Anwendung oder öffnet die Benutzte Objekte Tablett. Woraufhin bekomme ich folgende Fehlermeldung:

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

, die auf dieser Linie zeigt:

sh.unlockCanvasAndPost(canvas); 

Warum dies geschieht und wie kann ich es beheben?

EDIT: GESAMTE PROBLEMATISCHE CLASS

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"); 
    } 
} 
+0

Dies geschieht, weil Ihre Aktivität nicht mehr aktiv ist. Sie sollten die Schleife in 'onDestroy()' stoppen und erneut in 'onResume()' anhängen. Hast du das probiert? –

+0

@MatiasOlocco dies ist nicht in einer 'Activity' Klasse. Es befindet sich innerhalb einer 'SurfaceView'-Klasse – Ryan

+0

Immer noch verwenden Sie die Oberfläche, so sollten Sie aufhören, es zu verwenden, wenn Sie App in den Hintergrund gehen und die Verwendung fortsetzen, wenn es zurückkommt. –

Antwort

0

Überprüfen Sie, ob die Sichtbarkeit geändert hat, wenn es hat Pause/Resume-Schleife:

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); 
} 
+1

Konnte nicht nur mit: if (loop! = null) loop.setRunning (Sichtbarkeit! = VISIBLE) –

+0

@MatiasOlocco yep, das ist viel sauberer suchen. (immer noch nicht der größte bei Kürzungscode) – Ryan

+0

Überprüfen Sie diese Antwort, um den laufenden zu synchronisieren. Ansonsten sollte es in Ordnung sein: https://StackOverflow.com/a/25960100/3965050 –

Verwandte Themen