handler机制的通俗解释
文章最后的总结比较有用。
handler机制用于处理不同线程间的通信,因此,日志中会涉及到两个大类: Handler类 和 Thread类(实现了Runnable,因此不再单独说Runnable)几句话说清楚那些容易混淆的概念。
关于线程:
1、MessageQueue:用于存放线程放入的消息
2、Looper : 属于线程Thread ,是该Thread管理线程的工具。
关于Handler:
用于Thread线程间通讯,由于概念很抽象,可以将其描述为一个容易理解的过程:
如下:
而Android中,当一个页面启动时,会先分配一个主线程,该主线程又叫UI线程,从名字看就知道,这个线程是用来管理UI界面的,
例如界面的布局文件定义了一个按钮,那么,UI线程负责将按钮“画”界面上。但是最重要的是,主线程负责更新UI界面,且UI界面
只能由主线程来更新。
还有一个小要点需要知道:线程工作采用轮转法,例如我们在上网的时候同时在听歌,对于一个线程来说(其实会有若干个线程同时
管理上网和听歌这两件事情),他会先执行一会上网,然后再执行一会播放歌曲,这样轮流来。当然,由于我们的cpu灰常给力,我们
几乎察觉不到中间有什么停顿。ok。
话说回来,UI只能由主线程更新,但是,我们有时候需要执行一个耗时的工作,比如说客户端要去请求一个服务器,然后把请求回来的数据显示在UI上,我们知道,
访问网络是一个阻塞操作,当请求发送出去后,线程会等待,直到服务器端返回了数据,线程才会继续开始工作。如果在主线程中
进行访问网络的操作,那么等待服务器数据返回的过程中,主线程就没有办法再更行UI界面了。不过这不是重点,我们通常把这种耗时的操作
交给一个子线程去执行。这样主线程要做的只是创建一个子线程,然后把请求网络数据的任务交给这个子线程,然后继续干自己的事情。
问题来了:子线程请求回来数据,怎么把他写到UI上(前面我们说过更新UI是主线程的事情了)?
还记得刚才说过的handler吧,为了上面的情况,我们回到主线程创建子线程并交给子线程请求网络任务之前的瞬间,在这之前,我们可以在主线程中创建Handler
对象,然后实现该对象的handleMessage方法:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
};
};
现在可以捋一捋我们手中拿到的东西和他们的关系:
1、主线程
(1)handler(实现了handleMessage)
(2)looper(这个我们看不见,也不会直接调用,他只是伴随着一个线程必然会产生的)
(3)MessageQueue(有了handler我们也不会直接用到MessageQueue)
2、子线程
(1)looper(大家都是线程,我有个looper不过分吧!)
(2)MessageQueue(不解释了,太罗嗦)
下面就说说子线程请求回来的数据是如何被“画”到UI界面的。
步骤一、子线程将请求回来的消息放入自己的MessageQueue
步骤二、子线程的looper将该消息取出。
步骤三、子线程的looper将消息发送给handler
步骤四、主线程的looper将handler接收到的消息取出
步骤五、主线程的looper将刚才从handler拿到的消息存入主线程的MessageQueue
步骤六、主线程执行消息任务。
完
以上是我个人理解
想看专业的来这里