提问者:小点点

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


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

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

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


共2个答案

匿名用户

您需要在另一个线程上启动声音,这样它就不会阻塞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().Execute();若要停止任务,请调用PlaySoundTask().Cancel();

匿名用户

你可以用一个像这样的coroutine来做这个。 不知道时间会有多准确。

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
}