Android学习笔记(7)————Android中的消息机制
/********************************************************************************************
*
author:conowen@大
钟
* E-mail:conowen@hotmail.com
* http://blog.csdn.net/conowen
* 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。
********************************************************************************************/
1、Android管理线程的类
1.1、Message———MessageQueue的存放对象,各个线程之间交流的信息,线程处理完数据之后,需要更新UI,则发送Message给UI线程(即主线程)
1.2、MessageQueue———消息队列,用来存放Handler发送过来的消息。当然,存放Message并非实际意义的保存, 而是将Message以链表的方式串联起来的,等待Looper的抽取。
1.3、Looper———消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue就需要一个Looper。(也就是说一个Looper里面有一个Message Queue)
1.4、Handler———担当处理者角色,负责发送新消息到MessageQueue里面和处理消息,通知主线程更新UI
简述一下Android的消息传递过程
当子线程要发送Message给主线程时,首先要为当前线程创建一个Handler类对象,由Handler调用相应的方法,将需要发送的Message 发送到MessageQueue(消息队列)中,当Looper发现MessageQueue中有未处理的消息时就会将此消息广播出去,此时主线程的 Handler接收到此Message时,就会调用相应的方法来处理这条信息,完成主界面更新。(Looper与Handler的详细可参看第2、第3 点)
注:
a.一个线程只能有一个Looper对象,它是一个ThreadLocal,但是一个线程或者一个Looper可以对应多handler。
b.每一个Looper内部都有一个MessageQueue(消息队列),loop()方法被调用后,线程开始不断从队列中取出消息执行
c.Looper使一个线程变成Looper线程。
Looper Thread、Message Queue、Handler、Looper的大概架构图。
2、为线程创建Looper
除了主线程(main thread或称UI thread),Android系统启动会自动地位它建立一个Message
Queue,,当然地,也同时地建立了Looper。其他线程的话,Android系统不会自动为其建立Message
Queue的,要用户手动建立。一旦建立了Looper,Looper内部的Message Queue就会自动地建立了。
2.1、主线程
当Android系统启动主线程(UI线程)时,应用程序就会自动进入线程的main函数中,然后自动为主线程创建Looper
过程代码如下
- Looper.prepareMainLooper(); //建立消息队列,设置主Looper
- Looper.loop(); //启动消息循环,然后才能运作起来
- //此两段代码都在主线程中的main函数中
2.2、其它线程
其他线程Looper就要用户自己手动创建了。
具体方法如下:
在其他线程的run方法中里面写下如下代码
- public void run() {
- Looper.prepare(); //创建消息队列
- /**此处是线程的核心代码,用户自定义即可/
- Looper.loop(); //启动消息循环
- }
若要查看当前线程的Looper,调用Looper.myLooper();方法即可
Looper的其他方法
2.2.1、Looper.myLooper()得到当前线程Looper对象。
2.2.2、Looper.getThread()得到Looper对象所属线程。
2.2.3、Looper.quit()方法结束Looper循环。
3、Handler的使用
首先应该知道的是Handler的异步消息处理,异步是指,发送消息与处理消息不在同一时间。
首先Handler在其他线程中发出一个Message到消息队列中,而且发送消息的函数方法立刻返回,另外,在创建这个Handler的线程中,Looper将Message从消息队列中取出来,由Handler调用方法来处理消息。
举一个常见的例子:
在主线程中,创建一个Handler,然后在其他耗时比较长的线程中由Handler发出一个Message,同时,主线程中有Handler的处
理函数,Handler会处理这个发送过来的消息,从而更新UI。(因为主线程中系统已经自动地创建了一个Looper,(也就是说主线程也是一个
Looper线程),所以不用用户手动地创建Looper了)
Handler创建的时候,要关联一个Looper,默认是关联当前线程的Looper,当然了,也可以自己设定。
由于一个线程可以有多个Handler(Handler只有一个Looper),因此我们可以在同一个线程中创建多个Handler,如
- public class LooperThread extends Thread {
- private Handler myhandler1;
- private Handler myhandler2;
- @Override
- public void run() {
- // 当前线程变为Looper线程
- Looper.prepare();
- // 实例化两个handler
- myhandler1 = new Handler();
- myhandler2 = new Handler();
- // 开始循环处理消息队列
- Looper.loop();
- }
- }
发送消息:
Handler发送消息的方法如下,可以在任意线程中发送消息。
post(Runnable)
,postAtTime(Runnable,
long)
,postDelayed(Runnable, long)
,sendEmptyMessage(int)
,sendMessage(Message)
,sendMessageAtTime(Message,
long)
, sendMessageDelayed(Message, long)
发送的是Runnable对象与Message,事实上,Handler发送Runnable对象时,已经把其封装为Message了。所以Handler发送的都是Message。
Message发送的时候,已经附带着Handler的信息,也就是说从一个Message对象可以知道它是哪一个Handler的,所以Looper执行Message时,就知道该Message是哪个Handler发出的。
如定义一个Message msg
然后message.target方法返回的是发送这个的Message的Handler对象。
消息处理:
Handler是在(与自己关联的)线程中处理消息的,主要有两个方法。(一个线程可以有多个Handler)
转自:http://blog.csdn.net/conowen/article/details/7278123