Android Looper用法及原理

2021-07-26 10:00:54 字數 2350 閱讀 7318

looper是android為執行緒間非同步訊息通訊提供的一種機制,利用looper機制可以方便我們實現多執行緒程式設計時執行緒間的相互溝通。當然,如果不用looper而採用其它的執行緒間通訊方式(像管道,訊號量,共享記憶體,訊息佇列等)也是一樣的。looper的實現是利用訊息佇列的方式,為使用者封裝了一層api,使用者不需要考慮互斥加鎖的問題,方便使用者的使用。

(1)  looper的使用方法:

如果我們想建立乙個新的執行緒來執行新的任務,此時我們需要定義新的執行緒和建立新的執行緒物件;如果只是在當前執行緒增加非同步訊息處理,則不需要建立新的執行緒。更多的使用情況是建立新的執行緒,利用新的執行緒執行單獨的新任務。

//定義handler

public class workhandler extends handler

public void handlemessage(message msg) }

}//定義執行緒

private class testhandlerthread extends thread

@override

public void run() }

使用:

testhandlerthread testthread = newtesthandlerthread

();

message message = message.obtain();

message.arg1 = 1111;

message.what = x;

mworkhandler.sendmessage(message);//此時是在另乙個執行緒,通過直接訪問新執行緒中的變數向 testhandlerthread傳送訊息

(2)looper原理分析:

static final threadlocalsthreadlocal = new threadlocal();

public static void prepare()

private static void prepare(boolean quitallowed)

sthreadlocal.set(new looper(quitallowed));//建立looper物件,所以prepare必須放在最前面

}中。然後它呼叫了looper的構造方法。

private looper(boolean quitallowed)

looper構造方法中建立了乙個messagequeue

,且儲存了此messagequeue的引用,此messagequeue屬於looper所在的執行緒。

public static void loop()

final messagequeue queue = me.mqueue;

for (;;)

msg.target.dispatchmessage(msg);}}

loop()是乙個死迴圈,不斷的從當前執行緒的messagequeue中取資料,呼叫msg目標的dispatchmessage()。

下面我們看一下workhandler中的sendmessage函式

public final boolean sendmessage(message msg)

public final boolean sendmessagedelayed(message msg, long delaymillis)

return sendmessageattime(msg, systemclock.uptimemillis() + delaymillis);}

public boolean sendmessageattime(message msg, long uptimemillis)

return enqueuemessage(queue, msg, uptimemillis);}

workhander屬於新的執行緒,所以queue為剛才執行緒的looper建立的queue,即向目標執行緒的messagequeue中放入乙個新的訊息。

private boolean enqueuemessage(messagequeue queue, message msg, long uptimemillis)

return queue.enqueuemessage(msg, uptimemillis);}

此時loop()正在不斷迴圈等待訊息的到來,looper從messagequeue中獲取到訊息後,呼叫msg.target.dispatchmessage(msg);即為workhander的dispatchmessage()函式

public void dispatchmessage(message msg) else

}handlemessage(msg);}}

因為我們沒有定義callback函式,最後調到我們自定義的handlemessage()函式。

stack用法,queue用法,

stack stack 模板類的定義在標頭檔案中。stack 模板類需要兩個模板引數,乙個是元素型別,乙個容器型別,但只有元素型別是必要 的,在不指定容器型別時,預設的容器型別為deque。定義stack 物件的示例 如下 stack s1 stack s2 stack 的基本操作有 入棧,如例 s...

stack用法,queue用法,

stack stack 模板類的定義在標頭檔案中。stack 模板類需要兩個模板引數,乙個是元素型別,乙個容器型別,但只有元素型別是必要 的,在不指定容器型別時,預設的容器型別為deque。定義stack 物件的示例 如下 stack s1 stack s2 stack 的基本操作有 入棧,如例 s...

object args用法 args的用法

object args用法 args和 kwargs主要用於函式定義中。args和 kwargs允許您將可變數量的引數傳遞給函式。變數在這裡的含義是,您事先不知道使用者可以將多少個引數傳遞給您的函式,因此在這種情況下,您將使用這兩個關鍵字。args用於將非關鍵字的可變長度引數列表傳送到函式。這是乙個...