androidkotlintimertask

Update Timer interval time in Kotlin for Android


I am learning Kotlin/Android and I created a TimerTask to call an API every x seconds depending on user's choice in a dropdown menu. I can create the task, but when the user updates the interval(x) value in the menu, a new task is created and the previous keeps running.

I tried using cancel on the timer but the app crashes saying Timer already cancelled. How can I update the interval value of the timer and/or cancel the previous instances?

This is the TimerTask class:

import java.util.*
import java.util.concurrent.TimeUnit

class Schedule {
    private val timer = Timer()

    fun createTask(task: () -> Unit, intervalSeconds: Long) {
        val millisInterval:Long = TimeUnit.SECONDS.toMillis(intervalSeconds)
        val startDelay:Long = 0

        timer.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                task()
            }
        }, startDelay, millisInterval)
    }

    fun cancelPrevTask(){
            timer.cancel()
    }
}

And this is the implementation in the activity:

...

private val schedule = Schedule()
...

  override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
        val item = parent.getItemAtPosition(pos).toString()
        showMessage(this, item)
        val interval = item.toLong()
        
       // schedule.cancel() <- this crashes the app
       
       schedule.createTask(
            { readFileAndPost(this) },
            interval
        )

    }

Solution

  • I managed to solved making schedule a var and creating a new instance of the class after cancelling the task.

    This is the resulting activity:

    ...
    private var schedule = Schedule()
    ...
    override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
            val item = parent.getItemAtPosition(pos).toString()
            showMessage(this, item)
            val interval = item.toLong()
    
            schedule.cancelPrevTask()
            schedule = Schedule()
    
            schedule.createTask(
                { readFileAndPost(this) },
                interval
            )
    
        }