add MainDispatcher to replace Dispatchers.Main

This commit is contained in:
tursom 2020-07-18 23:23:15 +08:00
parent e5c7633f72
commit 71ce18234b
2 changed files with 47 additions and 10 deletions

View File

@ -0,0 +1,36 @@
package cn.tursom.utils.coroutine
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import java.io.Closeable
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.util.concurrent.Executors
import kotlin.concurrent.thread
import kotlin.coroutines.CoroutineContext
object MainDispatcher : MainCoroutineDispatcher(), Closeable {
private val dispatcher = Executors.newSingleThreadExecutor {
thread(start = false, block = it::run, name = "mainDispatcher", isDaemon = false)
}.asCoroutineDispatcher()
fun init() {
val mainDispatcherLoader = Class.forName("kotlinx.coroutines.internal.MainDispatcherLoader")
val dispatcher = mainDispatcherLoader.getDeclaredField("dispatcher")
dispatcher.isAccessible = true
val mf: Field = Field::class.java.getDeclaredField("modifiers")
mf.isAccessible = true
mf.setInt(dispatcher, dispatcher.modifiers and Modifier.FINAL.inv())
dispatcher.set(null, this)
}
override val immediate: MainCoroutineDispatcher get() = this
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatcher.dispatch(context, block)
}
override fun close() {
dispatcher.close()
}
}

View File

@ -1,8 +1,11 @@
package cn.tursom.utils.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.Closeable
import kotlin.coroutines.coroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
val testCoroutineLocal = CoroutineLocal<Int>()
@ -16,13 +19,11 @@ suspend fun testInlineCustomContext() {
println("===================")
}
suspend fun main() {
println(getContinuation())
suspendCoroutine<Int> { cont ->
println(cont)
cont.resume(0)
fun main() {
MainDispatcher.init()
GlobalScope.launch(Dispatchers.Main) {
println(Thread.currentThread().name)
}.invokeOnCompletion {
Dispatchers.Main.cast<Closeable>().close()
}
testCustomContext()
println(testCoroutineLocal.get())
testInlineCustomContext()
}