0
点赞
收藏
分享

微信扫一扫

Kotlin协程——与Android Handler的对比

sullay 2024-11-18 阅读 23

Kotlin协程的单线程 EventLoop 机制,其实就是 Android Handler 机制的原理,不过 Handler 是无限循环,当没有可执行的任务时会阻塞等待。 Android 为我们准备好了一个在 App 运行期间会一直运行的 main 线程,其在 ActivityThread 执行到 main 方法时会开启 loop,无限循环,精简的源码如下:

// android.app.ActivityThread.java
public static void main(String[] args) {
	 // 1. 以当前 main 线程 准备 mainLooper
    Looper.prepareMainLooper();

  	 // 2. 开始 loop 处理消息,当暂时没有消息时会阻塞 main 线程,直到有任务可以处理
    Looper.loop();
  
  	 // 3. 正常情况不会走到这里来
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

我们完全可以仿照 Handler 自己来实现一个简单的版本,实现类似于上面的无限循环和等待,看看下面的例子

class MyHandler {
    private val threadLocal: ThreadLocal<BlockingQueue<Runnable>> = ThreadLocal()
    private val blockingQueue: BlockingQueue<Runnable> = threadLocal.get() ?: LinkedBlockingQueue()

    fun postRunnable(runnable: Runnable) = blockingQueue.put(runnable)

    fun loop() {
        while (true) blockingQueue.take().run() // 当queue中没有Runnable时,take会阻塞,直到queue中有值可取
    }
}

val otherWork1 = Runnable { printlnWithThread("do work a") }
val otherWork2 = Runnable { printlnWithThread("do work X") }

fun main() {
    val myHandler = MyHandler()

    myHandler.postRunnable {
        printlnWithThread("do work 1")
        switchToBackThread(myHandler)
    }
    myHandler.postRunnable(otherWork1)
    myHandler.postRunnable(otherWork2)

    myHandler.loop()
    println("Main thread loop unexpectedly exited")
}

fun switchToBackThread(myHandler: MyHandler) = thread {
    printlnWithThread("do work 2")
    myHandler.postRunnable { printlnWithThread("do work 3") }
}

运行结果如下:

main: do work 1

main: do work a

main: do work X

Thread-0: do work 2

main: do work 3

符合我们的预期

举报

相关推荐

0 条评论