kotlinscheduled-tasks

How to schedule repeating task in kotlin?


I want to call some api in the background every X minutes and then process the json file I get

I've lokked into this documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/java.util.-timer/schedule.html

I'm new to kotlin (I used java before) and I have no idea how to use those functions, any examples of usage would be helpful.

Right now I have something like this:

Timer("NameOfMyTimer", true).schedule(refreshImages(knownPosts, knownFiles, httpClient), TimeUnit.MINUTES.toMillis(5))

And the result is:

None of the following functions can be called with the arguments supplied: 
public open fun schedule(p0: TimerTask!, p1: Date!): Unit defined in java.util.Timer
public open fun schedule(p0: TimerTask!, p1: Long): Unit defined in java.util.Timer

What did I wrong? How should I call those functions? I thought that I'm supposed to pass my function "refreshImages" to the timer with list of arguments it should be called with...? I think I just don't get the "function is object" philosophy right.


Solution

  • You're trying to call

    .schedule(refreshImages(knownPosts, knownFiles, httpClient), TimeUnit.MINUTES.toMillis(5))
    

    So you're passing as first argument the result of refreshImages(knownPosts, knownFiles, httpClient), and as second argument a number of milliseconds.

    And as you can see from the compilation error, the Timer class has two schedule() methods, but both expect a TimerTask as argument. And your refreshImages method doesn't return a TimerTask, so that doesn't compile.

    If you want to use one of these two Timer methods, you need to create an instance of TimerTask, and pass that as argument.

    My guess is that you would like to pass a function that will be executed after some delay. That's not what you're doing right now. What you're doing is that you execute refreshImages() immediately, and pass its returned value to schedule().

    Passing a function is not possible with the native Timer schedule method: it doesn't expect a function, but a TimerTask. But as the Kotlin documentation you linked to shows, it's possible by calling one of the extension functions of the Kotlin standard library.

    The signature of the schedule extension function is

    inline fun Timer.schedule(
        delay: Long,
        crossinline action: TimerTask.() -> Unit
    ): TimerTask
    

    So, as you can see, its first argument is a delay, and its second argument is a function with TimerTaskas receiver. So you can call this extension function using a delay as first argument, and a lambda as second argment:

    timer.schedule(TimeUnit.MINUTES.toMillis(5)) {
        refreshImages(knownPosts, knownFiles, httpClient)
    }