End SurfaceView y GameThread al salir de la aplicación

Tengo una vista de superficie y una clase gameThread. El juego Thread mantiene la actualización y la pintura en la clase SurfaceView.

Ahora cuando salgo de la aplicación (presionando el botón de inicio o de regreso) recibo un mensaje de que la aplicación se cerró. Eso es porque el GameThread todavía intenta dibujar en la superficie borrada …

Entonces, ¿cómo terminar correctamente la aplicación sin obtener esta notificación de cierre de la fuerza? Me gustaría que la clase GameThread se detuviera al presionar el botón Atrás. Debe hacer una pausa al presionar en casa y correr en segundo plano. Al volver a entrar en el juego todavía en ejecución, debe reanudar ….

¿Algunas ideas?

Esta es mi clase GameThread:

public class GameThread extends Thread{ private GameView view; public boolean isRunning = false; public GameThread(GameView view) { this.view = view; } public void setRunning(boolean setRunning) { isRunning = setRunning; } public void run() { while(isRunning) { Canvas c = null; view.update(); try { c = view.getHolder().lockCanvas(); synchronized (view.getHolder()) { view.draw(c); } }finally { if(c != null) { view.getHolder().unlockCanvasAndPost(c); } } } } 

Se mantiene actualizando mi clase GameView:

Clase pública GameView extends SurfaceView {

 private GameThread gameThread; public GameView(Context context, Activity activity) { super(context); gameThread = new GameThread(this); init(); holder = getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { } @Override public void surfaceCreated(SurfaceHolder holder) { gameThread.setRunning(true); gameThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); } public void init() { } public void update() { } public void draw(Canvas canvas) { super.draw(canvas); } } 

Al presionar el inicio de mi logcat muestra esto:

 02-24 18:24:59.336: E/SurfaceHolder(839): Exception locking surface 02-24 18:24:59.336: E/SurfaceHolder(839): java.lang.IllegalStateException: Surface has already been released. 02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.Surface.checkNotReleasedLocked(Surface.java:437) 02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.Surface.lockCanvas(Surface.java:245) 02-24 18:24:59.336: E/SurfaceHolder(839): at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:872) 

Actividad principal:

 public class MainActivity extends Activity { private RelativeLayout relativeLayout; private GameView gameView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gameView = new GameView(this, this); setContentView(R.layout.activity_main); relativeLayout = (RelativeLayout)findViewById(R.id.mainView); relativeLayout.addView(gameView); } @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); gameView.onBackPressed(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 

La Surface subyace a SurfaceView se destruye entre onPause() y onDestroy() en el ciclo de vida de la aplicación. Envíe un mensaje a su subproceso de procesador en onPause() y espere a que el subproceso se apague.

Para ver un ejemplo, vea la actividad "Hardware scaler exerciser" en Grafika . Inicia el subproceso de renderizado en la SurfaceHolder devolución de surfaceCreated() .

Actualización: se sentía extraño para iniciar el hilo en surfaceCreated() y detenerlo en onPause() , así que después de un poco de reorganización HardwareScalerActivity ahora se detiene el hilo en surfaceDestroyed() . (La documentación de SurfaceView es un poco ambigua – dice que la superficie es válida "entre surfaceCreated() y surfaceDestroyed() " – pero mirando a la aplicación SurfaceView esto parece ser el uso esperado.

Actualización 2: He actualizado el código un poco más después de encontrar casos que no manejar bien. Ahora hay un megacomment de 60 líneas en las fuentes, que también se puede ver en mi respuesta a una pregunta similar .

Actualización 3: El mega-comentario se convirtió en un apéndice doc de la arquitectura . La actividad de Grafika "hardware scaler exerciser" demuestra el enfoque # 2, mientras que "texture from camera" demuestra el enfoque # 1.

Bueno, usted puede hacer cambios en su código de esta manera.

En GameView

 @Override public void surfaceCreated(SurfaceHolder holder) { MainActivity obj=new MainActivity(); stop=obj.getBoolean(); //receive status of boolean from main activity //stop is boolean set if backPressed in main activity if(!stop){ gameThread.setRunning(true); gameThread.start(); } else gameThread.setRunning(false); } 

En MainActivity

 public Boolean getBoolean(){ return stop; } public void setBoolean(Boolean bools){ stop=bools; } @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); stop=true; setBoolean(stop); try{ Thread.sleep(200); // Be safeside and wait for Game thread to finish } catch(Exception e){ e.printStackTrace(); } MainActivity.finish(); } 

Llamar setBoolean una vez antes de backPress de lo contrario dará error. Haga las enmiendas al código según sus necesidades.

Espero eso ayude. Aclamaciones. 🙂

  • ¿Es esto posible tener la opinión de la textura para la cámara en forma circular para el androide?
  • ¿Cómo tomar una captura de pantalla de la vista de superficie de Android?
  • SurfaceView parpadeo / desgarro
  • Cámara androide2 procesa cada fotograma y muestra su vista previa
  • Anular onDraw () o draw ()?
  • Cómo capturar la imagen de CameraView personalizado en Android?
  • Vista superficial en capas en un FrameLayout en Android
  • Android VideoView.setAlpha no funciona (Xoom con 3.0)
  • Tomando capturas de pantalla mediante programación no captura el contenido de surfaceVIew
  • Filtro en vivo de la cámara Android
  • Ajuste de una vista previa de la cámara a un SurfaceView más grande que la pantalla
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.