相关文章推荐
暗恋学妹的煎饼  ·  resources - setrlimit ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams Please add that it is only available on android, since the question asks for a general kotlin method (although it does have the Android tag) Yoav Sternberg Apr 20, 2017 at 13:43 It's not constructive from your side. As a result when users will search android tag might think that this is wrong answer. Bogdan Ustyak Apr 20, 2017 at 20:27 For Android, it's better to use Handler than Timer : stackoverflow.com/questions/20330355/timertask-or-handler woprandi Apr 20, 2018 at 13:54

3. Using Executors class

Executors.newSingleThreadScheduledExecutor().schedule({
    TODO("Do something")
}, 2, TimeUnit.SECONDS)
                Can we do it synchronously , Handler is in Android package I believe. Is there any other way
– Akshay Hazari
                Feb 22, 2022 at 6:30
                Just to follow up on the comment regarding Handler().postDelayed being the best solution... that's deprecated now (at least in Android) and suggests Executors, so at least for Android I'd say that's the "best solution" (though Timer is also simple and straightforward)
– anabi
                Apr 14, 2022 at 7:18

example (thanks @Nguyen Minh Binh - found it here: http://jamie.mccrindle.org/2013/02/exploring-kotlin-standard-library-part-3.html)

import java.util.Timer
import kotlin.concurrent.schedule
Timer("SettingUp", false).schedule(500) { 
   doSomething()
                Thanks! Super easy. Found an example here jamie.mccrindle.org/2013/02/… Timer("SettingUp", false).schedule(500) { doSomething() }
– Nguyen  Minh Binh
                Apr 11, 2017 at 14:35
                It does compile, if you add these two imports: import java.util.Timer and import kotlin.concurrent.schedule
– Customizer
                Dec 31, 2017 at 0:29
                @Matias Elorriaga, for me, putting this on a new brand file doesn't compile, even adding the imports Customizer said
– Sulfkain
                Jan 16, 2018 at 9:09
                you don't need to put it on a file, that method is part of stdlib, follow the link in the first line of the answer,
– Matias Elorriaga
                Jan 16, 2018 at 13:38
                I originally thought this wouldn't compile even after importing kotlin.concurrent.schedule, because Kotlin merely complained of a signature mismatch, but then I realized I was trying to pass an Int instead of a Long. It compiled after correcting that.
– Joe Lapp
                Apr 30, 2019 at 15:19

You could launch a coroutine, delay it and then call the function:

 /*GlobalScope.*/launch {
   delay(1000)
   yourFn()

If you are outside of a class or object prepend GlobalScope to let the coroutine run there, otherwise it is recommended to implement the CoroutineScope in the surrounding class, which allows to cancel all coroutines associated to that scope if necessary.

Can you please explain me why I there's need to write "timerTask" instead of just braces? – Hugo Passos Dec 22, 2017 at 7:49 I think you do. Timer.schedule() expects a TimerTask as it's first argument. kotlin.concurrent.timerTask() wraps the given lambda in a TimerTask instance. See here: kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/… – Blieque Mar 27, 2018 at 17:18 Also, the given example can be condensed to one line if the Timer object isn't going to be used more than once, e.g., Timer().schedule(timerTask { ... }, 3000). A more Kotlin-friendly option is available too; see jonguer's answer. – Blieque Mar 27, 2018 at 17:20

If you're using more recent Android APIs the Handler empty constructor has been deprecated and you should include a Looper. You can easily get one through Looper.getMainLooper().

    Handler(Looper.getMainLooper()).postDelayed({
        //Your code
    }, 2000) //millis

If you are in a fragment with viewModel scope you can use Kotlin coroutines:

    myViewModel.viewModelScope.launch {
        delay(2000)
        // DoSomething()
                @paxcow it depends, if its just for a testing use case you can use the Main. But in any other case, I'd always use IO because you are delaying a task, similar what we do with an API request.
– Andy
                Dec 28, 2022 at 15:52
                Only specify dispatchers when you are calling blocking code, or when you're calling main-only code (like interacting with Views or LiveData and you aren't already on Dispatchers.Main).
– Tenfour04
                yesterday

If you are looking for generic usage, here is my suggestion:

Create a class named as Run:

class Run {
    companion object {
        fun after(delay: Long, process: () -> Unit) {
            Handler().postDelayed({
                process()
            }, delay)

And use like this:

Run.after(1000, {
    // print something useful etc.

i suggest to use kotlin coroutine and if you want to cancel it. its simple and light weight.

fun repeatFun(): Job {
    return coroutineScope.launch {  
        while(isActive) {
            //do your work here
            delay(1000)
//start the loop
val repeatFun = repeatRequest()
//Cancel the loop
repeatFun.cancel()

I recommended using SingleThread because you do not have to kill it after using. Also, "stop()" method is deprecated in Kotlin language.

private fun mDoThisJob(){
    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
        //TODO: You can write your periodical job here..!
    }, 1, 1, TimeUnit.SECONDS)

Moreover, you can use it for periodical job. It is very useful. If you would like to do job for each second, you can set because parameters of it:

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

TimeUnit values are: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS.

You still have to kill it when you navigate away from whatever is using it, or you'll leak the references it is capturing. – Tenfour04 yesterday

I use the following function(s):

fun <T> delayedAsyncTask(delayMs: Long = 0, task: () -> T): ScheduledFuture<T> {
    return Executors
        .newSingleThreadScheduledExecutor()
        .schedule(Callable<T> { task() }, delayMs, TimeUnit.MILLISECONDS)
fun <T> asyncTask(task: () -> T) = delayedAsyncTask(0, task)

Here's a unit test for the delayed function. Use of the returned future is optional of course.

    @Test
    fun `delayed task work correctly`() {
        val future = delayedAsyncTask(1000) {
            "lambda returns hello world"
        assertEquals(false, future.isDone)
        Thread.sleep(1100)
        assertEquals(true, future.isDone)
        assertEquals("lambda returns hello world", future.get())

Another way to create a redundant job other than this; that does not require the function to be suspend.

   val repeatableJob = CoroutineScope(Dispatchers.IO).launch {
        while (true) {
            delay(1000)

Cancel when you are done - repeatableJob.cancel()

Careful using an unmanaged CoroutineScope--this coroutine will leak memory and threads if not manually cancelled when the objects it captures references to become obsolete. It's the same issue GlobalScope has. More info here – Tenfour04 yesterday I do have suggested cancelling task above and the article just suggests the same manual cancellation or using withContext with suspend function, either way its not a difference with one exception where withContext blocks failure will result in cancellation of all coroutines associated with it, check this – MDT yesterday Yes, you recommended cancelling the Job. I was just adding a point, since using CoroutineScope().launch is a common anti-pattern some newbies use to avoid the GlobalScope warning without understanding the warning and when it is appropriate to use GlobalScope. – Tenfour04 yesterday fair point - there is no lifecycle owner in my way of creating coroutine. So yes manual clean up is mandatory. I do strictly use lifecycles events to cancel or recreate and also sometimes to manually cancel it and re-create when needed this way i have full control for adhoc scenarios. – MDT yesterday

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.