El hilo no interrumpe

Estoy aprendiendo a usar hilos en Android, y para hacer eso he hecho una pequeña aplicación que juega una serie de notas. La idea es que hay un botón de inicio y un botón de fin y que (obviamente) si presiona el botón de inicio que comienza a reproducir música, y si presiona el botón de finalización, se detiene. El botón de inicio funciona bien, pero el problema es que el botón de finalización no. Tengo problemas para averiguar por qué, así que tal vez algunos de ustedes pueden ayudarme. Este es el código:

public class PressAndPlay extends Activity { private volatile Thread initBkgdThread; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button startButton = (Button) findViewById(R.id.trigger); startButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { // create thread initBkgdThread = new Thread(new Runnable() { public void run() { play_music(); } }); initBkgdThread.start(); } }); Button endButton = (Button) findViewById(R.id.end); endButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { end_music(); } }); } int[] notes = {R.raw.c5, R.raw.b4, R.raw.a4, R.raw.g4}; int NOTE_DURATION = 400; MediaPlayer m_mediaPlayer; private void play_music() { for(int ii=0; ii<12; ii++) { //check to ensure main activity is not paused if(!paused) { if (m_mediaPlayer != null) {m_mediaPlayer.release();} m_mediaPlayer = MediaPlayer.create(this, notes[ii%4]); m_mediaPlayer.start(); try { Thread.sleep(NOTE_DURATION); } catch (InterruptedException e) { e.printStackTrace(); } } } } private void end_music() { if(initBkgdThread != null) { initBkgdThread.interrupt(); initBkgdThread = null; } } boolean paused = false; @Override protected void onPause() { paused = true; super.onPause(); } @Override protected void onResume() { super.onResume(); paused = false; } } 

One Solution collect form web for “El hilo no interrumpe”

Usted está llamando a interrupt() en el hilo de juego, pero es probable que esté esperando en el momento de sleep . Esto atrapará el sueño para lanzar una InterruptedException . Es necesario capturar esa excepción y salir del bucle para detener la reproducción:

  try { Thread.sleep(NOTE_DURATION); } catch (InterruptedException e) { // XXX need to stop playing here, maybe return or break? return; } 

Dado que la interrupt() también puede venir en un momento diferente, es necesario probar el estado de interrupción y cerrar el bucle:

  if (!paused && !Thread.currentThread().isInterrupted()) { ... 

Además, todas las variables que se comparten entre dos subprocesos necesitan ser synchronized o marcadas como volatile . La bandera paused probablemente debería ser volatile aquí:

 volatile boolean paused = false 

Por último, para la posteridad, cuando captura InterruptedException , elimina el estado de interrupción del subproceso. Por lo general, es una buena práctica establecer inmediatamente el indicador de interrupción en el hilo para que otros puedan probarlo:

  try { Thread.sleep(NOTE_DURATION); } catch (InterruptedException e) { // re-establish the interrupt condition Thread.currentThread.interrupt(); ... } 
  • Actualización de la interfaz de usuario desde un servicio (mediante un controlador?)
  • Android: Múltiples temporizadores en un ListView con manejador y ejecutables. 2 Problemas
  • Tomando un cómputo pesado del subproceso de la interfaz de usuario de Android
  • Contexto dentro de un Runnable
  • ¿Es este hilo seguro?
  • Android: ¿Qué hilo llama .onSensorChanged?
  • ¿Cómo poner un runnable en paquete?
  • Cómo implementar una cola de runnables
  • Una pregunta sobre Android runnable
  • ¿Cómo dejar de ejecutar cuando la aplicación va a fondo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.