2022年2月23日 星期三

Android Studio - Looper(訊息環)(四十九)

Android Studio - Looper(訊息環)(四十九):

Looper(訊息環)是 Android 提供的一種不斷的從 MessageQueue 中獲取新的 Message 資料機制,監視消息隊列,當發現消息隊列中有新消息的時候,便會把將 Message 發送給相應的 Handler 去處理。如果沒有消息可以處理,就阻塞在獲取消息過程中,直到一個新的消息產生。

Android Studio Looper 結構
Looper 本身具有執行緒私有性,Android 中每一個  Thread 都跟著一個 Looper,Looper 可以幫助 Thread 維護一個消息隊列,利用 Looper 機制可以方便我們實現多線程編程時線程間的相互溝通。
Android Studio Looper 與 Message Queue
定義一個 Looper Thread 例子:

//定義一個LooperThread

class LooperThread extends Thread{

                public Handler mHandler;

                public void run(){

                                //調用prepare

                                Looper.prepare();

                                ...

                                //進入消息迴圈

                                Looper.loop();

                }

}

 

//應用程式使用LooperThread

{

....

new LooperThread().start();//啟動執行緒

}


調用函數 Looper 的 prepare() 例子:

public static final void prepare(){

                //一個Looper只調用一次prepare

                if(sThreadLocal.get()!=null){

                                throw new RuntimeException("Only one looper maybe create per thread");

                }

                //構造一個Looper物件,並設置到調用線程的區域變數中。

                sThreadLocal.set(new Looper());

}

//sThreadLocal的定義

public static final ThreadLocal sThreadLocal=new ThreadLocal();


調用線程就是 LooperThread 的 Run 線程,Looper 物件的構造例子:

private Looper(){

                //構造一個訊息佇列

                mQueue=new MessageQueue();

                mRun=true;

                mThread=Thread.currentThread();

                //得到當前線程的Thread物件

}


通過代碼 Looper 封裝了一個訊息佇列,Looper 的 prepare 函數把當前這個 Looper 和調用這個 prepare 的執行緒綁定在一起了(也就是處理線程) ,處理 Thread 調用 Loop 函數,處理來自該訊息佇列的消息。當訊息源向 Looper 發送消息的時候,其實是把消息添加到這個 Looper 的訊息佇列中,消息是由與 Looper 綁定的調用 Thread 來處理。

調用函數 Looper 迴圈例子:

public static final void loop(){

                //myLooper返回保存在ThreadLocal調用線程中返回的Looper對象

                Looper me=myLooper();

                //取出Looper的訊息佇列

                MessageQueue queue=me.mQueue;

                while(true){

                                Message msg=queue.netxt();

                                //處理消息,Message消息中有一個targettargetHandler類型

                                //如果target為空,則退出消息迴圈

                                if(msg!=null){

                                                if(target==null){

                                                                return;

                                                }

                                                //調用該消息的Handler,交給它的dispatchMessage函數處理

                                                msg.target.dispatchMessage();

                                                msg.recycle();

                                }

                }

}

//myLooper函數返回調用線程的線程區域變數,也就是保存在其中的Looper物件

public static final Looper myLooper(){

                return (Looper)sThreadLocal.get();

}


2022年 2月 23日(Wed)天氣報告
氣溫:23.0°F / -5.0°C @ 07:00
風速:每小時 5公里
降雨機會:1%
相對濕度:百分之 56%
天氣:晴

沒有留言:

張貼留言