4

I'm trying to figure out how to use an extension function to run any method with a delay, but can't seem to figure it out.

I am trying something like below where I have a function and I want a handler to delay the execution by a certain timeInterval:

functionX().withDelay(500)
functionY().withDelay(500)

private fun Unit.withDelay(delay: Int) {
  Handler().postDelayed( {this} , delay)}

private fun Handler.postDelayed(function: () -> Any, delay: Int) {
  this.postDelayed(function, delay)}

Anyone?

zsmb13
  • 85,752
  • 11
  • 221
  • 226
Rik van Velzen
  • 1,977
  • 1
  • 19
  • 37

4 Answers4

7

Another approach would be to declare a top-level (i.e. global) function like this:

fun withDelay(delay : Long, block : () -> Unit) {
    Handler().postDelayed(Runnable(block), delay)
}

Then you can call it, from anywhere, like this:

withDelay(500) { functionX() }
Sam
  • 8,330
  • 2
  • 26
  • 51
6

You should put the extension on the function type, not Unit:

fun functionX() {}
fun functionY() {}

private fun (() -> Any).withDelay(delay: Int) {
     Handler().postDelayed(this , delay)
}

Usage:

::functionX.withDelay(500)
::functionY.withDelay(500)

Here, ::functionX is a reference to the global function called functionX.

Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
2

Or I like this version too:

Wrap whatever code block you want to be executed within { ... }

{ invokeSomeMethodHere() }.withDelay()

And have an extension function that invokes the Runnable after a certain delay:

fun <R> (() -> R).withDelay(delay: Long = 250L) {

    Handler().postDelayed({ this.invoke() }, delay)
}
Rik van Velzen
  • 1,977
  • 1
  • 19
  • 37
  • Thanks for sharing! – Wahib Ul Haq Jul 20 '18 at 11:01
  • 1
    It has one issue though which I found out today. If you use it inside a callback, it doesn't work unless you add a `;` in previous statement because it considers previous line as part of the expression on which it is invoked. – Wahib Ul Haq Aug 03 '18 at 15:14
0

For example, you can declare your global variables like:

private var handler: Handler = Handler()
private lateinit var runnableNewUrlBackground: Runnable

And also declare the function as global

init {
    runnableNewUrlBackground = Runnable {
        // Your function code here
        myCustomFun();
    }
}

Then, when you want to call this, just use:

handler.postDelayed(runnableNewUrlBackground, YOUR_DESIRED_TIME)
Marc LaQuay
  • 199
  • 1
  • 6