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分三步走:
- 判定是否已有并
Looper.prepare()
- 做一些准备工作(如暴露handler等)
- 调用
Looper.loop()
,线程进入阻塞态
- Looper.getMainLooper()
Looper.myLooper()
获取当前线程绑定的Looper,如果没有返回null
。Looper.getMainLooper()
返回主线程的Looper
,这样就可以方便的与主线程通信。注意:在Thread
的构造函数中调用Looper.myLooper
只会得到主线程的,因为此时新线程还未构造好
下面给一段代码,通过Thread,Looper和Handler实现线程通信:
HandlerThread 和 AsyncTask
Android为了方便对Thread
和Handler
进行封装,也就是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的效率不是很高而且资源代价也比较重,只有当进行一些小型操作时为了方便起见使用。这一点在官方文档写的很清楚:
由于使用比较简单应该不需要细说。如有需要会在未来更新。