I am running a handler that updates a textView element. The handler is started and stopped at the click of a button but once I start it, I cannot stop it.
fun updateTextView(handler: Handler, run: Boolean = true) {
val runnable: Runnable = object : Runnable {
override fun run() {
// update text view element
handler.postDelayed(this, 500)
}
}
if (run) handler.postDelayed(runnable, 500)
// this should stop it?
else handler.removeCallbacks(runnable)
}
And my function to detect clicks
val textHandler = Handler(Looper.getMainLooper())
private fun setupClickListeners() {
startLive.setOnClickListener{
updateTextView(textHandler)
}
stopLive.setOnClickListener{
updateTextView(textHandler, run = false)
}
}
This is a general way to do what you need:
Like I said in the comment, your version is creating a new
Runnableinstance every time you run the function - then after posting it to the queue, it immediately removes it again. If you didn't remove it, it would run - but you wouldn't be able to stop it, because you don't have a stored reference to the instance you created, so you can't pass it toremoveCallbacks. (Running the function again like you're doing just creates a newRunnable, so cancelling that won't affect the other one.)By storing the
Runnableas a variable, you have access to it - so you can easily pass it toremoveCallbacks, and reuse it by posting it again. This doesn't work if you actually need multiple instances (like you have separate tasks going on) - in that case, you'd need to store references to eachRunnableyou create, and have some way to coordinate which one you're cancelling