Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.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
Android 运行函数,直到用户单击按钮_Android_Kotlin - Fatal编程技术网

Android 运行函数,直到用户单击按钮

Android 运行函数,直到用户单击按钮,android,kotlin,Android,Kotlin,我正在尝试开发一个包含节拍器的应用程序,以用户指定的间隔重复音调。我可以让节拍器播放-这是由onClick事件触发的,但应用程序在我创建的startMetronome()函数中被锁定。我知道这是为什么,我只是尽量确保我能够播放音调,并在用户定义的时间间隔重复: private fun startMetronome(interval: Long) { while (true) { soundPool?.play(soundId, 1F, 1F, 0, 0,

我正在尝试开发一个包含节拍器的应用程序,以用户指定的间隔重复音调。我可以让节拍器播放-这是由onClick事件触发的,但应用程序在我创建的
startMetronome()
函数中被锁定。我知道这是为什么,我只是尽量确保我能够播放音调,并在用户定义的时间间隔重复:

private fun startMetronome(interval: Long) {
        while (true) {
            soundPool?.play(soundId, 1F, 1F, 0, 0, 1F)
            Thread.sleep(interval)
        }
    }

显然,这永远不会离开
startMetronome()
函数并锁定应用程序(我也希望如此)。我只是不知道如何触发此功能,然后允许应用程序按钮仍处于活动状态,允许触发“中断”,然后以调整的间隔启动此功能。

您需要在另一个线程上启动声音,以便它不会阻塞UI线程,实现这一点的最基本方法是通过异步任务

伪代码:

private class playSoundTask extends AsyncTask<Void, Void, Void> {

     protected Void doInBackground(Integer... interval) {
           if (!isCancelled()){
             //start playing the sound
           } else{
            //stop playing the sound
           } 
     }

     protected void onProgressUpdate(Void... progress) {
        
     }

     protected void onPostExecute(Void result) {
      
     }
 }
 
私有类playSoundTask扩展了AsyncTask{
受保护的Void doInBackground(整数…间隔){
如果(!isCancelled()){
//开始播放声音
}否则{
//停止播放声音
} 
}
受保护的void onProgressUpdate(void…progress){
}
受保护的void onPostExecute(void结果){
}
}
启动任务调用
playSoundTask().execute()

停止任务调用
playSoundTask().cancel()

您需要在另一个线程上启动声音,这样它就不会阻塞UI线程,最基本的方法是通过异步任务

伪代码:

private class playSoundTask extends AsyncTask<Void, Void, Void> {

     protected Void doInBackground(Integer... interval) {
           if (!isCancelled()){
             //start playing the sound
           } else{
            //stop playing the sound
           } 
     }

     protected void onProgressUpdate(Void... progress) {
        
     }

     protected void onPostExecute(Void result) {
      
     }
 }
 
私有类playSoundTask扩展了AsyncTask{
受保护的Void doInBackground(整数…间隔){
如果(!isCancelled()){
//开始播放声音
}否则{
//停止播放声音
} 
}
受保护的void onProgressUpdate(void…progress){
}
受保护的void onPostExecute(void结果){
}
}
启动任务调用
playSoundTask().execute()

停止任务调用
playSoundTask().cancel()

您可以使用这样的协同程序来实现这一点。我不知道时间会有多准确

private var metronomeJob: Job? = null

private fun startMetronome(interval: Long) {
    metronomeJob?.cancel()
    metronomeJob = lifecycleScope.launch(Dispatchers.IO) {
        while (isActive) {
            soundPool?.play(soundId, 1F, 1F, 0, 0, 1F)
            delay(interval)
        }
    }
}

private fun stopMetronome() {
    metronomeJob?.cancel()
    metronomeJob = null
}

您可以通过这样的协同程序来实现这一点。我不知道时间会有多准确

private var metronomeJob: Job? = null

private fun startMetronome(interval: Long) {
    metronomeJob?.cancel()
    metronomeJob = lifecycleScope.launch(Dispatchers.IO) {
        while (isActive) {
            soundPool?.play(soundId, 1F, 1F, 0, 0, 1F)
            delay(interval)
        }
    }
}

private fun stopMetronome() {
    metronomeJob?.cancel()
    metronomeJob = null
}

首先,为什么要使用
线程.sleep()
?如果阻塞线程只会浪费资源,请使用诸如
delay()
之类的协程函数或任何其他不阻塞线程的异步方法。我只是使用我想到的第一件事来测试“延迟”,以确认实际的声音以正确的间隔播放。但是谢谢你提供的信息。你为什么要首先使用
线程.sleep()
?如果阻塞线程只会浪费资源,请使用诸如
delay()
之类的协程函数或任何其他不阻塞线程的异步方法。我只是使用我想到的第一件事来测试“延迟”,以确认实际的声音以正确的间隔播放。但是谢谢你提供的信息,谢谢。这通常是可行的,但当间隔小于1秒(间隔=1000)时,会出现大量失真和剪切。很难说是音频文件本身还是什么,因为音频变得如此混乱。基本上,我的测试是30bpm(精细)、60bpm(精细)、61bpm(出现问题)。猜猜是什么原因造成的吗?对不起,没有。我对音频播放没有太多的研究。谢谢。这通常是可行的,但当间隔小于1秒(间隔=1000)时,会出现大量失真和剪切。很难说是音频文件本身还是什么,因为音频变得如此混乱。基本上,我的测试是30bpm(精细)、60bpm(精细)、61bpm(出现问题)。猜猜是什么原因造成的?对不起,没有。我对音频播放没有太多研究。