这个东西真的很新,所以忍受我!
在我的应用程序中,我需要提示用户通过按下按钮响应噪音,并在声音播放时记录响应。我还需要一个可变的声音呈现时间,以及声音之间的可变时间......
我面临的问题是我需要一种方法在声音的呈现之间发出延迟,并在声音播放和声音停止命令之间有延迟。我理解使用wait()我需要使用另一个线程,这样我就不会暂停UI线程。
我需要一些帮助,这是最优雅的方式吗?目前我有这个:
public void onClick(View v) {
switch (v.getId()){
case R.id.start:
presentTone(1000,60,2000,"l");
// I need to insert a delay here, or in the presentTone method body
break;
我的presentTone方法就是这样:
private void presentTone(int frequency,int amplitude,final int length,String side){
// GETTING THE CORRECT AMPLITUDE LEVEL
// Find the correction level as a float
correctionDB = calibrationOffsets.get(frequency + "L");
// Decibels for 5 dB drops
volLog = (float) (Math.pow(10,((amplitude-100)/20)));
// Multiply the decibels correction with the presentation level to get the calibrated level if the offset is positive
volLog = (float) (volLog*(Math.pow(10,((correctionDB)/20))));
// Check to see if the system is capable of the 80 dB desired level
if (volLog>1){
Toast.makeText(this, "Over Error - System is not capable of this amplitude level!" ,Toast.LENGTH_LONG).show();
}
//PICKING THE CORRECT HEADPHONE SIDE TO PLAY
volLogL = volLog;
volLogR = volLog;
if (side.toLowerCase().contains("l")){
volLogR = (float) 0.0;
}else if (side.toLowerCase().contains("r")){
volLogL = (float) 0.0;
}
//PLAYING THE TONE
// Playing the tone
mp.reset();
mp = MediaPlayer.create(this,idReferences.get(freq_selection));
mp.setVolume(volLogL, volLogR);
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp.isPlaying()) {
mp.stop();
mp.reset();
}
try {
mp.start();{
//* I need to add a delay here, so I think I need to run the whole "Playing the tone" section in another thread?
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
});
}
我需要新线程在presentTone方法中,这样我就可以开始播放,延迟一段时间,然后停止。我还需要反馈一个布尔值来判断声音是否正在播放,以便我可以处理用户响应。
道歉,如果我问的不清楚,我正在尽力让它变得明显!我很感激任何帮助。感谢
答案 0 :(得分:0)
public void onClick(View v) {
switch (v.getId()){
case R.id.start:
new Thread(new Runnable(){
public voir run(){
Thread.sleep(_time_);
presentTone(1000,60,2000,"l");
}
}).start();
break;
这应该有用。
这样它就不会暂停主线程。
答案 1 :(得分:0)
这是一个小线程示例,您可以尝试并在您自己的情况下使用它。例如,此处的while
循环仅由TaskObject
的活动状态控制,但您可以添加自己的条件,或者向Task
添加方法以控制循环。< / p>
Task
将等同于您的presentTone(...)
方法,这是您要在另一个主题中运行的任务。
public class Task implements Runnable {
private final TaskObject object;
private int executionTick = 0;
public Task(final TaskObject object) {
this.object = object;
}
@Override
public void run() {
this.object.start();
try {
while (this.object.isActive()) {
if (this.executionTick == 10) {
this.object.stop();
} else {
System.out.println(this.executionTick++ + ": " + this.object.getName());
Thread.sleep(1000L);
}
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
TaskObject
将是该任务管理的对象。在这里,我创建了一个通用的,但这相当于你的声音,音调或媒体来源。
public class TaskObject {
private String name;
private boolean active = false;
public TaskObject(final String name) {
this.name = name;
}
public void setName(final String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void start() {
this.active = true;
}
public void stop() {
this.active = false;
}
public boolean isActive() {
return this.active;
}
}
这是测试。
public class Test {
public static void main(String[] args) throws Exception {
// The object we want to manage or track with the task.
TaskObject executedObject = new TaskObject("Foo");
// Executing the task.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new Task(executedObject));
executor.shutdown();
// Wait in this thread and change the name of the object.
Thread.sleep(3000L);
executedObject.setName("New Name");
// Wait for the end of the task.
executor.awaitTermination(15L, TimeUnit.SECONDS);
}
}
输出:
0: Foo
1: Foo
2: Foo
3: New Name
4: New Name
5: New Name
6: New Name
7: New Name
8: New Name
9: New Name
请注意,这只是一个通用示例,您可以更好地了解如何处理多线程实现,而不是复制粘贴! :)
如果您有任何疑问,请随时询问!