Skip to content

Commit c2fba3a

Browse files
qwwdfsadelizarov
authored andcommittedJul 18, 2018
Provide HandlerContext.immediate extension to immediately execute tasks which are invoked from the right context
Fixes #381
1 parent 14968cd commit c2fba3a

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed
 

‎binary-compatibility-validator/reference-public-api/kotlinx-coroutines-android.txt

+2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ public final class kotlinx/coroutines/experimental/android/HandlerContext : kotl
1010
public fun delay (JLjava/util/concurrent/TimeUnit;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
1111
public fun dispatch (Lkotlin/coroutines/experimental/CoroutineContext;Ljava/lang/Runnable;)V
1212
public fun equals (Ljava/lang/Object;)Z
13+
public final fun getImmediate ()Lkotlinx/coroutines/experimental/android/HandlerContext;
1314
public fun hashCode ()I
1415
public fun invokeOnTimeout (JLjava/util/concurrent/TimeUnit;Ljava/lang/Runnable;)Lkotlinx/coroutines/experimental/DisposableHandle;
16+
public fun isDispatchNeeded (Lkotlin/coroutines/experimental/CoroutineContext;)Z
1517
public fun scheduleResumeAfterDelay (JLjava/util/concurrent/TimeUnit;Lkotlinx/coroutines/experimental/CancellableContinuation;)V
1618
public fun toString ()Ljava/lang/String;
1719
}

‎ui/kotlinx-coroutines-android/src/HandlerContext.kt

+29-4
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,41 @@ private const val MAX_DELAY = Long.MAX_VALUE / 2 // cannot delay for too long on
2525

2626
/**
2727
* Implements [CoroutineDispatcher] on top of an arbitrary Android [Handler].
28-
* @param handler a handler.
29-
* @param name an optional name for debugging.
3028
*/
31-
public class HandlerContext(
29+
public class HandlerContext private constructor(
3230
private val handler: Handler,
33-
private val name: String? = null
31+
private val name: String?,
32+
private val invokeImmediately: Boolean
3433
) : CoroutineDispatcher(), Delay {
34+
/**
35+
* Creates [CoroutineDispatcher] for the given Android [handler].
36+
*
37+
* @param handler a handler.
38+
* @param name an optional name for debugging.
39+
*/
40+
public constructor(
41+
handler: Handler,
42+
name: String? = null
43+
) : this(handler, name, false)
44+
45+
@Volatile
46+
private var _immediate: HandlerContext? = if (invokeImmediately) this else null
47+
48+
/**
49+
* Returns dispatcher that executes coroutines immediately when it is already in the right handler context
50+
* (current looper is the same as [handler] looper). See [isDispatchNeeded] documentation on
51+
* why this should not be done by default.
52+
*/
53+
public val immediate: HandlerContext = _immediate ?:
54+
HandlerContext(handler, name, true).also { _immediate = it }
55+
3556
@Volatile
3657
private var _choreographer: Choreographer? = null
3758

59+
override fun isDispatchNeeded(context: CoroutineContext): Boolean {
60+
return !invokeImmediately || Looper.myLooper() != handler.looper
61+
}
62+
3863
override fun dispatch(context: CoroutineContext, block: Runnable) {
3964
handler.post(block)
4065
}

0 commit comments

Comments
 (0)