Android中的Thread, Looper和Handler机制(附带HandlerThread与AsyncTask)

    • 接收消息的“消息队列”
    • 阻塞式地从消息队列中接收消息并进行处理的“线程”
    • 可发送的“消息的格式”
    • “消息发送函数”

    与之对应,Android中的实现对应了

    • 接收消息的“消息队列” ——【MessageQueue】
    • 可发送的“消息的格式” ——【Message
    • “消息发送函数”——【Handler的post和sendMessage】

    一个类似一个消息泵。它本身是一个死循环,不断地从MessageQueue中提取Message或者Runnable。而Handler可以看做是一个Looper的暴露接口,向外部暴露一些事件,并暴露sendMessage()post()函数。

    在安卓中,除了UI线程/主线程以外,普通的线程(先不提HandlerThread)是不自带Looper的。想要通过UI线程与子线程通信需要在子线程内自己实现一个Looper。开启Looper分三步走

    1. 判定是否已有并Looper.prepare()
    2. 做一些准备工作(如暴露handler等)
    3. 调用Looper.loop(),线程进入阻塞态
    • Looper.getMainLooper()

    Looper.myLooper()获取当前线程绑定的Looper,如果没有返回nullLooper.getMainLooper()返回主线程的Looper,这样就可以方便的与主线程通信。注意:Thread的构造函数中调用Looper.myLooper只会得到主线程的,因为此时新线程还未构造好

    下面给一段代码,通过Thread,Looper和Handler实现线程通信:


    HandlerThread 和 AsyncTask

    Android为了方便对ThreadHandler进行封装,也就是HandlerThread。文档中对HandlerThread的定义是:

    HandlerThread继承自Thread,说白了就是Thread加上一个一个Looper。分析下面的代码:

    会抛出java.lang.RuntimeException: Only one Looper may be created per thread错误。如果我们把super.run()注释掉就不会有这样的错误。显然在super.run()中进行了Looper的绑定。

    AsyncTask是谷歌对Thread和Handler的进一步封装,完全隐藏起了这两个概念,而用doInBackground(Params... params)取而代之。但需要注意的是AsyncTask的效率不是很高而且资源代价也比较重,只有当进行一些小型操作时为了方便起见使用。这一点在官方文档写的很清楚:

    由于使用比较简单应该不需要细说。如有需要会在未来更新。