Lennac
Lennac

Reputation: 186

Run function until user clicks a button

I'm trying to develop an app that includes a metronome, repeating a tone at an interval specified by the user. I'm able to get the metronome to play - this is triggered by an onClick event, but the app becomes locked in the startMetronome() function I created. I know why this is, I was just mostly trying to ensure that I was able to get the tone to play and have it repeat at the user defined intervals:

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

Obviously this never leaves the startMetronome() function and locks the app (again, I expect this). I'm just not sure how to trigger this function and then allow the app buttons to still be active, allowing for an "interrupt" to be triggered and this function to be then started with an adjusted interval.

Upvotes: 0

Views: 71

Answers (2)

Tenfour04
Tenfour04

Reputation: 93551

You can do this with a coroutine like this. Not sure how accurate the timing would be.

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
}

Upvotes: 2

Scott Johnson
Scott Johnson

Reputation: 715

You would need to start the sound on another thread so it doesn't block the UI Thread, the most basic way to do this would be via a Async Task

Pseudo code:

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) {
      
     }
 }
 

To start the task call playSoundTask().execute(); To stop the task call playSoundTask().cancel();

Upvotes: 0

Related Questions