我正在尝试使用循环来调用线程来播放声音。它似乎打电话和玩好。
但是,我希望能够让用户在点击“暂停”时退出循环。按钮。我设置了布尔变量" PauseClicked"允许这个。
我认为我遇到的问题 - 我不知道如何更新" PauseClicked"从我的主线程变量。你知道如何在循环运行的同时从主线程更新这个变量吗?
我们将非常感谢您提供的任何帮助。我花了很多时间没有成功。我不确定的特定代码如下(更新变量的尝试位于第三行):
// Import statements
public class MyActivity extends Activity {
boolean PauseClicked = false;
// .... Other variables and onCreate....
public void whenPlayClicked(View view) {
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
//Setup playing variables
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume / maxVolume;
float rightVolume = curVolume / maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1f;
//temporary sleep counters
int blueSleep = (BlueCount * 1000);
int greenSleep = (GreenCount * 1000);
int redSleep = (RedCount * 1000);
int orangeSleep = (OrangeCount * 1000);
int bellSleep = 4000;
int cyclesPlayed = 0;
// Loop - loop until either 1) all cycles have been played. (i.e repeat number of times selected from Spinner).
// or 2)Pause button is clicked.
for (PauseClicked = false; (cyclesPlayed < cycleCount) && (PauseClicked == false); cyclesPlayed++) {
if (blueSleep > 0) {
soundPool.play(blueSoundID, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
SystemClock.sleep(blueSleep);
}
if (greenSleep > 0) {
soundPool.play(greenSoundID, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
SystemClock.sleep(greenSleep);
}
if (redSleep > 0) {
soundPool.play(redSoundID, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
SystemClock.sleep(redSleep);
}
if (orangeSleep > 0) {
soundPool.play(orangeSoundID, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
SystemClock.sleep(orangeSleep);
}
// CheckForPause();
}
if (TotCount > 0) {
SystemClock.sleep(bellSleep);
soundPool.play(bellSoundID, 0.05F, 0.05F, priority, no_loop, normal_playback_rate);
SystemClock.sleep(bellSleep);
}
return null;
}
@Override
protected void onPostExecute(String result) {
textView2.setText("We are returning from call to ASynch task.");
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
public void whenPauseClicked(View view) {
Toast.makeText(getApplicationContext(), "All sounds were paused", Toast.LENGTH_SHORT).show();
PauseClicked = true;
soundPool.autoPause();
}
答案 0 :(得分:1)
你需要使用AtomicBoolean,在你的情况下使用这种布尔值 - 当多个线程访问它时。 尝试将PauseClicked的定义更改为
AtomicBoolean PauseClicked = new AtomicBoolean(false);
在您的代码中,当您尝试访问它时,请使用它来获取和设置方法。 如果有效,请告诉我。
答案 1 :(得分:0)
volatile
应该没问题,除非您正在执行复合操作(但是,我没有看到任何,但您可能希望在某些您未提供的代码中使用它们),例如正如AtomicBoolean
中提供的那些,您将使用它们。
由于易失性布尔值保证原子写入和读取,因此应该设置它。它们略微比AtomicBoolean快,但差别小于1纳秒,这可以忽略不计。