Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android多线程-播放声音的计时;响应_Java_Android_Multithreading_Audio - Fatal编程技术网

Java Android多线程-播放声音的计时;响应

Java Android多线程-播放声音的计时;响应,java,android,multithreading,audio,Java,Android,Multithreading,Audio,这东西真的很新,所以请容忍我 在我的应用程序中,我需要通过按下按钮提示用户对噪音做出响应,如果只有在声音播放时才发生,则记录响应。我还需要一个可变的声音呈现时间,以及声音之间的可变时间 我面临的问题是,我需要一种方法来在声音呈现之间发出延迟,并在声音播放和声音停止命令之间发出延迟。我知道要使用wait(),我需要使用另一个线程,这样就不会暂停UI线程 我需要一些帮助,哪种方法最优雅?目前,我有以下几点: public void onClick(View v) { switch (v.

这东西真的很新,所以请容忍我

在我的应用程序中,我需要通过按下按钮提示用户对噪音做出响应,如果只有在声音播放时才发生,则记录响应。我还需要一个可变的声音呈现时间,以及声音之间的可变时间

我面临的问题是,我需要一种方法来在声音呈现之间发出延迟,并在声音播放和声音停止命令之间发出延迟。我知道要使用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方法中,这样我就可以开始播放,延迟一段时间,然后停止。我还需要反馈声音是否播放的布尔值,以便处理用户响应

道歉如果我问的不清楚,我会尽我所能让你明白!我将感谢任何帮助。谢谢

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;
这应该行得通


这样它就不会暂停主线程。

这里有一个小线程示例,您可以尝试在自己的情况下使用它来实现。例如,此处的
while
循环仅由
任务对象的活动状态控制,但您可以添加自己的条件,或向
任务添加方法来控制循环

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
请注意,为了更好地理解如何实现多线程,这只是一个通用示例,而不是复制粘贴!)


如果您有任何问题,请随时提问

请您在代码中添加注释,说明您正试图在另一个线程中执行哪个部分,或者您正试图完成什么多线程任务?嗨,Alexis,-为了清晰起见,删除了以前的注释-我想我需要在另一个线程中播放“音调”部分,以便我可以播放音调,等等,然后停止音调。我假设我将能够传递一个布尔值,说明此时是否正在播放音调以处理用户响应?我是否可以尝试在方法体中实现这一点?这样做的原因是,我可以启动声音,暂停,然后停止声音,并将其干净地放在方法中?非常感谢你的帮助,所以非常感谢亚历克西斯!一个问题;你有更多的文档或者简单的指南吗?看起来像是我想要的,但看起来我需要阅读一些背景知识和基础知识…@LeeDavison我发现这是一个很好的起点,但你可以随时查看遗嘱执行人的情况。@LeeDavison一件好事也是自己尝试一些简单的情况以获得更多的放松,然后用更复杂的代码实现它。我的回答就是一个例子:)