Android 多线程 Handler 的使用

  • Android,多线程,Thread,Handler
  • 2020.07.14

看了很多网上的关于 Android 多线程,Handler 、 Thread 的博客,虽然很多博客的篇幅很大,道理说的很多,但是示例代码几乎全是错的,搞得真是郁闷。

默认的线程是没有 Looper 的,我们要使用 Looper 需要手动调用 Looper.prepare() 和 Looper.loop() 。

class MyThread : Thread(){
    var mLooper : Looper ?= null
    override fun run(){
        Looper.prepare()
        // prepare() 后,这个线程才有 Looper 对象。
        // mLooper = Looper.myLooper()
        Looper.loop()
    }
}

Handler 在实例化的时候,需要指定一个 Looper ,如果不指定的话,Handler 会使用当前线程的 Looper 。比如你在一个 onClick() 方法里用 Handler 的无参构造器实例化了一个 Handler ,那么这个 Handler 绑定的 Looper 是主线程的 Looper 。

一种大概率错误的写法

如果我们想实例化 Handler 对象并且绑定到 MyThread 的 Looper 上,那么我们需要得到 MyThread 的 Looper 对象,比如

val myThread = MyThread()
myThread.start()
val handler = Handler(myThread.mLooper)

这样写是有问题的,myThread.start() 调用完了, myThread.mLooper 不一定是有值的。所以这样的写法是错误的。这种写法比较适合调用 Thread.start() 方法和实例化 Handler 存在明显的时间差的情况下。

一种基本保证正确的写法

另外一个种写法是在调用 Looper.prepare() 后,去实例化一个 Handler .

class MyThread : Thread(){
    var mHandler : Handler ?= null
    override fun run(){
        Looper.prepare()
        // prepare() 后,这个线程才又 Looper 对象。
        // mHandler = Handler()...
        Looper.loop()
    }
}

重要的事情

重要的事情再说一次,获取 looper 对象,必须在线程 run 起来后,调用 Looper.prepare() 方法之后。

相关文章

- EOF -

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动。
转载请注明:文章转载自 Binkery 技术博客 [https://binkery.com]
本文标题: Android 多线程 Handler 的使用
本文地址: https://binkery.com/archives/2020.07.14-Android-Thread-Handler.html