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

过程代码如下

  1. Looper.prepareMainLooper();   //建立消息队列,设置主Looper  
  2. Looper.loop();  //启动消息循环,然后才能运作起来  
  3. //此两段代码都在主线程中的main函数中  

 

2.2、其它线程

其他线程Looper就要用户自己手动创建了。

具体方法如下:

在其他线程的run方法中里面写下如下代码

 

  1. public void run() {  
  2. Looper.prepare();   //创建消息队列  
  3.  /**此处是线程的核心代码,用户自定义即可/  
  4. Looper.loop();    //启动消息循环  
  5. }  

若要查看当前线程的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,如

  1. public class LooperThread extends Thread {  
  2.     private Handler myhandler1;  
  3.     private Handler myhandler2;  
  4.   
  5.     @Override  
  6.     public void run() {  
  7.         // 当前线程变为Looper线程  
  8.         Looper.prepare();  
  9.   
  10.         // 实例化两个handler  
  11.         myhandler1 = new Handler();  
  12.         myhandler2 = new Handler();  
  13.           
  14.         // 开始循环处理消息队列  
  15.         Looper.loop();  
  16.     }  
  17. }  

发送消息:

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

posted @ 2012-06-04 16:51  hnrainll  阅读(511)  评论(0编辑  收藏  举报