4
4
5
5
package kotlinx.coroutines.experimental.android
6
6
7
- import android.os.Handler
8
- import android.os.Looper
9
- import android.view.Choreographer
7
+ import android.os.*
8
+ import android.view.*
10
9
import kotlinx.coroutines.experimental.*
11
- import java.util.concurrent.TimeUnit
12
- import kotlin.coroutines.experimental.CoroutineContext
10
+ import java.util.concurrent.*
11
+ import kotlin.coroutines.experimental.*
13
12
14
13
/* *
15
14
* Dispatches execution onto Android main UI thread and provides native [delay][Delay.delay] support.
@@ -32,9 +31,26 @@ public class HandlerContext(
32
31
private val handler : Handler ,
33
32
private val name : String? = null
34
33
) : CoroutineDispatcher(), Delay {
34
+
35
+ /* *
36
+ * Dispatcher which executes given block immediately if [isDispatchNeeded] is already in the right handler context
37
+ * (current looper is the same as [handler] looper). If not, block is dispatched regularly via [handler]
38
+ */
39
+ public val immediate: HandlerContext by lazy { HandlerContext (handler, name, true ) }
40
+
41
+ private var invokeImmediately: Boolean = false
42
+
43
+ private constructor (handler: Handler , name: String? , invokeImmediately: Boolean ) : this (handler, name) {
44
+ this .invokeImmediately = invokeImmediately
45
+ }
46
+
35
47
@Volatile
36
48
private var _choreographer : Choreographer ? = null
37
49
50
+ override fun isDispatchNeeded (context : CoroutineContext ): Boolean {
51
+ return ! invokeImmediately || Looper .myLooper() != handler.looper
52
+ }
53
+
38
54
override fun dispatch (context : CoroutineContext , block : Runnable ) {
39
55
handler.post(block)
40
56
}
@@ -68,7 +84,7 @@ public class HandlerContext(
68
84
// post into looper thread thread to figure it out
69
85
return suspendCancellableCoroutine { cont ->
70
86
handler.post {
71
- updateChoreographerAndPostFrameCallback(cont)
87
+ updateChoreographerAndPostFrameCallback(cont)
72
88
}
73
89
}
74
90
}
0 commit comments