我正在学习如何在 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
中等待。这将导致 sleep 抛出一个 InterruptedException
。您需要捕获该异常并退出循环以停止播放:
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()) {
...
此外,两个线程之间共享的所有变量都需要同步
或标记为volatile
。 paused
标志在这里可能是volatile
:
volatile boolean paused = false
最后,为了后代,当您捕获 InterruptedException
时,它会清除线程的中断状态。通常最好立即在线程上设置中断标志,以便其他人可以对其进行测试:
try {
Thread.sleep(NOTE_DURATION);
} catch (InterruptedException e) {
// re-establish the interrupt condition
Thread.currentThread.interrupt();
...
}
关于java - 即使我正在调用 thread.interrupt() 线程也不会中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9791361/