歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android-初識Handler,Looper,Message(-) 源碼

本文只是表面的帶大家浏覽下Handler,Looper,Message的源碼

Android的消息處理有三個核心類:Looper,Handler和Message。其實還有一個Message Queue(消息隊列),

異步處理大師 Handler:

什麼是handler?handler扮演了往MQ上添加消息和處理消息的角色(只處理由自己發出的消息),即通知MQ它要執行一個任務(sendMessage),並在loop到自己的時候執行該任務(handleMessage),整個過程是異步的。handler創建時會關聯一個looper,默認的構造方法將關聯當前線程的looper,不過這也是可以set的。默認的構造方法:

 
  1. public class handler {     
  2.     
  3.     final MessageQueue mQueue;  // 關聯的MQ      
  4.     final Looper mLooper;  // 關聯的looper      
  5.     final Callback mCallback;     
  6.     // 其他屬性      
  7.     
  8.     public Handler() {     
  9.         if (FIND_POTENTIAL_LEAKS) { // 沒看懂,直接略過,,,      
  10.             final Class<? extends Handler> klass = getClass();     
  11.             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&     
  12.                     (klass.getModifiers() & Modifier.STATIC) == 0) {     
  13.                 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +     
  14.                     klass.getCanonicalName());     
  15.             }     
  16.         }     
  17.         // 默認將關聯當前線程的looper      
  18.         mLooper = Looper.myLooper();     
  19.         // looper不能為空,即該默認的構造方法只能在looper線程中使用     
 
  1.         //UI主線程中默認帶有一個Looper   
  2.         if (mLooper == null) {     
  3.             throw new RuntimeException(//不能在沒有Looper的線程上創建Handler,      
  4.                 "Can't create handler inside thread that has not called Looper.prepare()");     
  5.         }     
  6.         // 重要!!!直接把關聯looper的MQ作為自己的MQ,因此它的消息將發送到關聯looper的MQ上      
  7.         mQueue = mLooper.mQueue;     
  8.         mCallback = null;     
  9.     }     
  10.     
  11.     // 其他方法      
  12. }    

當然這只是Handler的一個構造方法。Handler本身有四個構造函數,其他其他的三個你可以通過查看源碼來解析,大致雷同。

Handler發送消息

有了handler之後,我們就可以使用 post(Runnabl),sendMessage(Message)這些方法向MQ上發送消息了。光看這些API你可能會覺得handler能發兩種消息,一種是Runnable對象,一種是message對象,這是直觀的理解,但其實post發出的Runnable對象最後都被封裝成message對象了,見源碼:
Post發送的形式

  1. public final boolean post(Runnable r){//使用Post發送消息   
  2.       return  sendMessageDelayed(getPostMessage(r), 0);  
  3. }  
 
  1. private final Message getPostMessage(Runnable r) {//把一個Runnable包轉成一個Message   
  2.        Message m = Message.obtain();  
  3.        m.callback = r;  
  4.        return m;  
  5. }  
 
  1. public final boolean sendMessageDelayed(Message msg, long delayMillis){  
  2.        if (delayMillis < 0) {  
  3.            delayMillis = 0;  
  4.        }  
  5.        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);  
  6. }  
 
  1. <pre class="java" name="code"><pre class="java" name="code">public boolean sendMessageAtTime(Message msg, long uptimeMillis){  
  2.         boolean sent = false;  
  3.         MessageQueue queue = mQueue;  
  4.         if (queue != null) {  
 
  1. /*該handler對象,這確保了looper執行到該message時能找到處理它的handler,直白點就是ABC三個Handler發送消息,最終執行的時候Message消息  
 
  1. 也是由他們本身來執行,而不會發生A接受到B發送的Message之類的情況*/  
  2.            msg.target = this;//  
 
  1.     sent = queue.enqueueMessage(msg, uptimeMillis);//壓入消息隊列   
  2. }else {  
  3.     RuntimeException e = new RuntimeException(  
  4.         this + " sendMessageAtTime() called with no mQueue");  
  5.     Log.w("Looper", e.getMessage(), e);  
  6. }  
  7. return sent;  

sendMessage(Message)形式

  1.  public final boolean sendMessage(Message msg){  
  2.         return sendMessageDelayed(msg, 0);  
  3. }  
 
  1. public final boolean sendMessageDelayed(Message msg, long delayMillis){  
  2.        if (delayMillis < 0) {  
  3.            delayMillis = 0;  
  4.        }  
  5.        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);  
  6.  }  

從源碼中我們中我們可以很清晰的看到無論是用psot(Runnable)還是使用sendMessage(Message)方法,最後他們都會調用到同一個方法壓入都一個隊列中去。

Copyright © Linux教程網 All Rights Reserved