久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Android異步消息處理

 dmw_zgl 2015-03-18

最近看了《Android內核剖析》這本書,,將學習筆記整理如下

1. 異步消息線程

異步消息線程不同一般線程的是,,它的線程run方法有一個無限循環(huán),沒循環(huán)一次,,從其內部的消息隊列中取出一個消息并調用回調函數(shù)進行處理,。如果消息隊列為空,線程暫停,,直到消息隊列中有新的消息,。

 

一般而言有兩種需求需要用到異步線程處理:

(1) 任務需要常駐

(2) 任務需要根據外部傳遞的消息做出不同的操作

 

2. Android異步線程的實現(xiàn)方法

 

在線程的內部有一個或多個Handler對象,外部程序通過該handler對象向線程發(fā)送異步消息,,消息經由Handler傳遞到MessageQueue對象中,。線程內部只能包含一個MessageQueue對象,線程主執(zhí)行函數(shù)從MessageQueue中讀取消息,,并回調Handler對象中的回調函數(shù)handleMessage(),。下面的代碼是一個簡單的實例。

 

 

Java代碼  收藏代碼
  1. class LooperThread extends Thread {  
  2.     public Handler mHandler;  
  3.       
  4.     public void run() {  
  5.         Looper.prepare();  
  6.           
  7.         mHandler = new Handler() {  
  8.             public void handleMessage(Message msg) {  
  9.                 // process incoming messages here  
  10.             }  
  11.         };  
  12.           
  13.         Looper.loop();  
  14.     }  
  15. }  

 

2.1 Looper

Looper的作用有兩點,,第一是調用靜態(tài)函數(shù)prepare()為線程創(chuàng)建一個消息隊列,;第二是調用靜態(tài)函數(shù)loop(),使調用該函數(shù)的線程進行無限循環(huán),,并從消息隊列中讀取消息,。

(1)調用prepare()函數(shù)

 

Java代碼  收藏代碼
  1. public static final void prepare() {  
  2.     if (sThreadLocal.get() != null) {  
  3.         throw new RuntimeException("Only one Looper may be created per thread");  
  4.     }  
  5.     sThreadLocal.set(new Looper());  
  6. }  

   //Looper構造函數(shù)  

 

Java代碼  收藏代碼
  1. private Looper() {  
  2.       mQueue = new MessageQueue();  
  3.       mRun = true;  
  4.       mThread = Thread.currentThread();  
  5.   }  

 在代碼中,變量sThreadLocal的類型是ThreadLocal,,該類的作用是提供“線程局部存儲”,,從變量的作用域來理解下這個概念。

 

函數(shù)成員變量-------------------------------- 僅在函數(shù)內部有效
類成員變量 --------------------------------- 僅在對象內部有效
線程局部存儲(TLS)變量-------------------- 在本線程內的任何對象內保持一致
類靜態(tài)變量------------------------------------ 在本進程內的任何對象內保持一致
跨進程通信(IPC)變量----------------------- 一般使用Binder進行定義,,在所有進程中保持一致

 

 

 

 

 

 

 

 

從上述的代碼可以看到,,一個線程只允許創(chuàng)建一個Looper對象,這是因為每個Looper對象都會創(chuàng)建一個MessageQueue對象,,一個異步線程中只能有一個消息隊列,,所以也就只能有一個Looper對象

(2)調用loop()函數(shù)

 

Java代碼  收藏代碼
  1. public static final void loop() {  
  2.         Looper me = myLooper();  
  3.         MessageQueue queue = me.mQueue;  
  4.           
  5.         // Make sure the identity of this thread is that of the local process,  
  6.         // and keep track of what that identity token actually is.  
  7.         Binder.clearCallingIdentity();  
  8.         final long ident = Binder.clearCallingIdentity();  
  9.           
  10.         while (true) {  
  11.             // might block 如果隊列為空,則當前線程就會被掛起,,next()函數(shù)內部會暫停線程  
  12.             Message msg = queue.next();  
  13.               
  14.             if (msg != null) {  
  15.                 if (msg.target == null) {  
  16.                     // No target is a magic identifier for the quit message.  
  17.                     return;  
  18.                 }  
  19.                 if (me.mLogging!= null) me.mLogging.println(  
  20.                         ">>>>> Dispatching to " + msg.target + " "  
  21.                         + msg.callback + ": " + msg.what  
  22.                         );  
  23.                 //回調函數(shù)完成對消息的處理,。msg.target的類型是Handler,msg最終交予handleMessage()處理  
  24.                 msg.target.dispatchMessage(msg);  
  25.                 if (me.mLogging!= null) me.mLogging.println(  
  26.                         "<<<<< Finished to    " + msg.target + " "  
  27.                         + msg.callback);  
  28.                   
  29.                 // Make sure that during the course of dispatching the  
  30.                 // identity of the thread wasn't corrupted.  
  31.                 final long newIdent = Binder.clearCallingIdentity();  
  32.                 if (ident != newIdent) {  
  33.                     Log.wtf("Looper", "Thread identity changed from 0x"  
  34.                             + Long.toHexString(ident) + " to 0x"  
  35.                             + Long.toHexString(newIdent) + " while dispatching to "  
  36.                             + msg.target.getClass().getName() + " "  
  37.                             + msg.callback + " what=" + msg.what);  
  38.                 }  
  39.                 //回收message對象占用的系統(tǒng)資源  
  40.                 msg.recycle();  
  41.             }  
  42.         }  
  43.     }  
   

 

2.2 MessageQueue

消息隊列采用排隊方式對消息進行處理,,即先到的消息會先得到處理,,但如果消息本身指定了被處理的時刻,,則必須等到該時刻才能處理該消息。

 

2.3 Handler

盡管MessageQueue提供了直接讀/寫的函數(shù)接口,,但對于應用程序員而言,,一般不直接讀/寫消息隊列。

程序員一般使用Handler類向消息隊列發(fā)送消息,,并重載Handler的handleMessage函數(shù)添加消息處理代碼,。

handler對象只能添加到有消息隊列的線程中,否則會發(fā)生異常,。因此,在構造Handler對象前,,必須已經執(zhí)行過Looper.prepare(),,但prepare()不能被執(zhí)行兩次。

一個線程中可以包含多個Handler對象,。在Looper.loop函數(shù)中,,不同的Message對應不同的Handler對象,從而回調不同的handleMessage函數(shù),。

異步消息處理線程處理用于多線程的消息傳遞外,,它還和跨進程調用(IPC)一起被使用,用于實現(xiàn)異步跨進程調用,。

 

 

 

 

 

 


 

    本站是提供個人知識管理的網絡存儲空間,,所有內容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多