Android的消息机制

来源:互联网 发布:js正则表达式.* 编辑:程序博客网 时间:2024/06/09 17:37

关键字简单介绍

Message(消息)
MessageQueue(消息队列)
Looper(通过死循环不断读取消息队列的消息)
Handler(发送,接受并处理消息)

ui线程的消息循环在ActivityThread.main方法中创建,该函数为Android应用程序的入口。执行该方法后应用程序就启动了,并且不断从消息队列中取数据,然后处理数据。

在子线程中完成耗时操作,好多情况下需要更新UI,但是不能在自线程中更新UI,此时需要用到handler来更新,我们通过handler将
消息post到UI线程中,然后通过handler的handlermessage方法更新ui(注意,这个handler必须在UI线程创建,否则没办法更新ui,呵呵呵呵呵,因为handler要和UI线程的消息队列关联,后面说)。

Looper

而就内部而言,消息队列没什么好介绍的。每个Handler都关联了一个Looper对象,Looper对象来管理Message队列,实质上looper就是建立一个死循环(while(true)这样的)从消息队列中取出消息。
Looper 的几个方法:
Looper.prepare()来创建looper对象(消息队列封装其中)
Looper.loop()执行循环
注意:以上两个方法都是成对出现的

Handler

当初Handler发送消息实际上是将Message投入到消息队列中,调用Looper.getLooper()获取Looper对象,Looper从消息队列又将消息分发给Handler处理

在Handler中的几个方法:
dispatchMessage()分发的方法

如果Runnable类型的callBack为空则执行handlerMessage来处理消息,我们将UI的更新消息写在其中;如果callback不为空,则执行handlerCallback来处理,该方法会调用callback的run方法
上面说的其实是handler的两种分发机制,比如我们post(Runnable callback)callback则不为空,通常我们使用Handler来sendMessage时不会设置callback,所以就执行了handleMessage这个机制。

说一下callback这个机制
设置callback后,Runnable对象会包装成Message对象,并将Runnable对象设置为Message对象的callback字段,最后将该Message对象插入队列

不管是post Runnable对像还是message对象都会调用sendMessageDelayed(msg,time)方法。

在线程中创建Handler为什么会报错??

当你在子线程中创建Handler对象时,如果Looper为空,就会抛出异常

"Can't create handler inside thread that has not called Looper.prepare()"

这是因为每个Thread都有自己的Looper对象,但是可以为空,但是创建handler后就要与管理消息队列的Looper对象关联,此时Looper还没创建,所以就会抛出异常,因此创建Handler时Looper一定不能为空,解决办法如下:

Looper.prepare();handler=new Handler();Looper.loop();

关于为什么UI线程下不用调用Looper的两个方法?因为在Activity Thread.main方法中已经调用了Looper.prepareMainLooper()和Looper.loop()方法,所以全部都要调用这对方法!

1 0
原创粉丝点击