如何在 Kotlin 中杀死协程?

How to kill a coroutine in Kotlin?

我想用 Kotlin 为 Android 创建一个节拍器应用程序。我正在启动点击播放协程:

playBtn.setOnClickListener {
        if (!isPlaying) {
            playBtn.setText(R.string.stop)
            isPlaying = true
        }
        else {
            isPlaying = false
            playBtn.setText(R.string.play)
        }

        if (isPlaying) {
            GlobalScope.launch {
                while (isPlaying) {
                    delay(bpmToMillis)
                    launch { metro1.start() }
                }
            }
        }
    }

它工作正常,但如果您快速点击“播放”按钮,它会启动另一个线程并伴有节拍器声音。因此,它不是一次“点击”,而是几乎没有延迟地播放两到三个。

我尝试移动代码块并使用 sleep 和 TimeUnit,但它不起作用。

我是菜鸟,请不要讨厌:)

playBtn.setOnClickListener {
    if (!isPlaying) {
        playBtn.setText(R.string.stop)
        isPlaying = true
    }
    else {
        isPlaying = false
        playBtn.setText(R.string.play)
    }

    if (isPlaying) {
// assigned coroutine scope to variable 
        var job = GlobalScope.launch {
            while (isPlaying) {


if(isActive){
                delay(bpmToMillis)
                launch { metro1.start() }
}
            }
//some condition to cancel the coroutine
job.cancel()
        }
    }
}

感谢大家的帮助!你把我推向了正确的方向。

如果我添加带有 null 或空协程的新 var,播放不会出现问题的唯一方法是:

var job: Job? = null
// or
var job: Job = GlobalScope.launch {}

然后在 if 语句中赋值:

playBtn.setOnClickListener {
        if (!isPlaying) {
            playBtn.setText(R.string.stop)
            isPlaying = true
        }
        else {
            isPlaying = false
            playBtn.setText(R.string.play)
            //job cancel here
            job?.cancel()
        }
        if (isPlaying) {
            //var assigment here
            job = GlobalScope.launch {
                while (isPlaying) {
                    metro1.start()
                    delay(bpmToMillis)
                }
            }
        }
    }

否则从上层看不到工作,我认为你不能在需要时真正取消它:)