即使我正在调用thread.interrupt(),线程也不会中断

我正在学习如何在Android中使用线程,为此,我做了一个小应用程序,它会播放一系列音符。 这个想法是有一个开始按钮和一个结束按钮(显然)如果按下开始按钮它开始播放音乐,如果你按下结束按钮,它就会停止。 启动按钮工作正常,但问题是结束按钮没有。 我无法弄清楚原因,所以也许你们中的一些人可以帮助我。 这是代码:

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

你正在播放线程上调用interrupt()但它可能正在等待sleep 。 这将捕获睡眠以抛出InterruptedException 。 您需要捕获该exception退出循环以停止播放:

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

由于interrupt()也可以在不同的时间进行,因此您需要测试中断状态并退出循环:

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

此外,两个线程之间共享的所有变量都需要synchronized或标记为volatilepaused标志应该是volatile

 volatile boolean paused = false 

最后,对于后代,当您捕获InterruptedException ,它会清除线程的中断状态。 通常最好立即在线程上设置中断标志,以便其他人可以测试它:

 try { Thread.sleep(NOTE_DURATION); } catch (InterruptedException e) { // re-establish the interrupt condition Thread.currentThread.interrupt(); ... }