Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 668
0vOiCQne Avatar asked Oct 23 '25 07:10

0vOiCQne


1 Answers

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

like image 160
JB Nizet Avatar answered Oct 25 '25 23:10

JB Nizet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!