2010-06-30 12 views
9

Aquí está mi situación: Estoy creando un juego para Android y la actividad de mi juego se compone de un SurfaceView personalizado que tiene un hilo para la lógica del juego y la representación. La arquitectura es similar a la demo LunarLander del sitio web de Google."Subproceso ya iniciado" al reanudar la actividad

Cuando se inicia la actividad que crea la SurfaceView y llama a este método:

@Override 
    public void surfaceCreated(SurfaceHolder holder) 
    { 
     renderThread.start(); 
    } 

Al pulsar el botón de inicio para salir del juego, el método onPause() se llama, que llama surfaceDestroyed(). En surfaceDestroyed dejo el juego Thread llamando al:

@Override 
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
     synchronized(holder) 
     { 
      renderThread.stop(); 
     } 
    }  

La aplicación va bien al fondo. Luego, cuando reinicio la aplicación presionando el ícono, aparece el mensaje "Subproceso ya iniciado" en el registro junto con una ventana emergente "forzar cierre" en la pantalla. Este mensaje ocurre cuando la actividad ingresa al método "surfaceCreated" cuando llama a start() en el hilo de renderizado.

Ahora lo he visto durante horas y no puedo entender por qué es esto. Creo que mi hilo se detiene cuando cierro la aplicación, así que no entiendo por qué dice que ya ha comenzado.

Respuesta

8

Esos métodos no hacen lo que crees que hacen. Desde el API doc:

Nunca es legal para iniciar un hilo más de una vez.

Y:

public final void stop() - desuso. Este método es inherentemente inseguro.

Si desea hacer una pausa en un hilo, se tienen que utilizar Object.wait() y Objecft.notifyAll() desde el interior de la rosca.

+1

Hola, gracias por la respuesta. Reemplacé a stop() por un join() en un ciclo while. Creo que espera antes de detener el hilo. Pero todavía tengo el mismo problema, ¿me estoy perdiendo algo? En cuanto al inicio del hilo. Entiendo que el hilo no se puede iniciar más de una vez, por lo tanto, el mensaje de error. Entonces, ¿crees que obtengo este error solo porque el hilo no se detiene correctamente? Gracias – NioX5199

+1

@ NioX5199: no, join() tampoco detiene el hilo, espera a que termine por sí solo. Obtiene el error porque el subproceso ya está iniciado. Los hilos * no * pueden "detenerse" y reiniciarse. Como escribí: para hacer que un hilo se detenga hasta que se cumpla una condición, se usa Object.wait(). –

+0

Probablemente tampoco debería hacerlo de esa manera. Volver a crear el hilo es probablemente un mejor enfoque. – alexanderblom

0

una mala solución, pero funciona ..

public void surfaceCreated(SurfaceHolder holder) { 
     try{ 
     _thread.setRunning(true); 
     _thread.start(); 
     }catch(Exception ex){ 
      _thread = new TutorialThread(getHolder(), this); 
      _thread.start(); 
     } 

    } 

correcciones son bienvenidos.

+0

Si bien esto funcionará (fsvo), generalmente no es una buena idea detectar problemas de forma intencionada y luego intentar corregirlos. En cambio, sea * proactivo * y devuelva a las Excepciones su significado. –

5

En mi opinión, no debe empaquetar el código en una subclase de subproceso si tiene la intención de iniciar y detener el subproceso con frecuencia (los ejemplos lo hacen porque hace que el código sea más corto). Use un Runnable en su lugar. De esta forma, puede detener y descartar el hilo viejo cuando lo desee y crear un nuevo objeto hilo para ejecutar el ejecutable cuando necesite volver a iniciarlo.

private TutorialRunnable tutorialRunnable; 

... 

// Synchronization and error checking omitted for brevity. 
public void surfaceCreated(SurfaceHolder holder) { 
    thread = new Thread(tutorialRunnable); 
    thread.start(); 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    tutorialRunnable.setRunning(false); 
    while (thread != null) { 
     try { 
      thread.join(); 
      thread = null; 
     } catch (InterruptedException e) { 
     } 
    } 
} 

Además, confiar en las excepciones es mala forma. Eso debería usarse como último recurso cuando su propio código se comporta de forma inesperada.

Cuestiones relacionadas