非同步訊息機制

2021-07-23 19:21:05 字數 2736 閱讀 3715

1.  乙個執行緒裡面只有乙個looper。

2. 子執行緒也可建立handler。

前後需分別加上looper.prepare();和looper.loop();

標準寫法:

looper.prepare();

handler mhandler =

newhandler()

}};looper.loop();

在prepare 中建立looper。

3. 主線程對應的方法在activitythread的main方法中。

4. looper的構造方法中初始化了乙個messagequeue物件

private

looper

(boolean

quitallowed)

總:looper.prepare()方法初始話了乙個looper物件並關聯在乙個messagequeue物件,並且乙個執行緒中只有乙個looper物件,只有乙個messagequeue物件。而handler的構造方法則在handler內部維護了當前執行緒的looper物件

5. handler.sendmessage(msg) 會呼叫queue.enqueuemessage(msg, uptimemillis);,會發現 messagequeue並沒有使用列表將所有的message儲存起來,而是使用message.next儲存下乙個message,從而按照時間將所有的message排序;

6. looper.loop()

可以看到looper.loop()方法裡起了乙個死迴圈,不斷的判斷messagequeue中的訊息是否為空,如果為空則直接return掉,然後執行queue.next()方法

可以看到其大概的實現邏輯就是message的出棧操作,裡面可能對執行緒,併發控制做了一些限制等。獲取到棧頂的message物件之後開始執行:

msg.target

.dispatchmessage

(msg);

handle的dispatchmessage()

/**  

* handle system messages here. */

public

void

dispatchmessage

(message msg)

else}

handlemessage(msg);}}

可以看到,如果我們設定了callback(runnable物件)的話,則會直接呼叫handlecallback方法:

private

static

void

handlecallback

(message message)

msg.callback為空的話,會直接呼叫我們的mcallback.handlemessage(msg),即handler的handlermessage方法。由於handler物件是在主線程中建立的,所以handler的handlermessage方法的執行也會在主線程中

原作者的總結:

1)主線程中定義handler,直接執行:

handler mhandler =

newhandler() };

而如果想要在子執行緒中定義handler,則標準的寫法為:

// 初始化該執行緒looper,messagequeue,執行且只能執行一次

looper.prepare();

// 初始化handler物件,內部關聯looper物件

handler mhandler =

newhandler() };

// 啟動訊息佇列出棧死迴圈

looper.loop();

2)乙個執行緒中只存在乙個looper物件,只存在乙個messagequeue物件,可以存在n個handler物件,handler物件內部關聯了本執行緒中唯一的looper物件,looper物件內部關聯著唯一的乙個messagequeue物件。

3)messagequeue訊息佇列不是通過列表儲存訊息(message)列表的,而是通過message物件的next屬性關聯下乙個message從而實現列表的功能,同時所有的訊息都是按時間排序的。

5)activity內部預設存在乙個handler的成員變數,android中一些其他的非同步訊息機制的實現方法: 

handler的post方法:

mhandler.post(

newrunnable()

});檢視其內部實現:

public

final

boolean

post

(runnable r)

可以發現其內部呼叫就是sendmessage系列方法。。。

view的post方法:

public

boolean

post

(runnable action)

// assume that post will succeed later

viewrootimpl.getrunqueue().post(action);

return

true;

} 可以發現其呼叫的就是activity中預設儲存的handler物件的post方法。

activity的runonuithread方法:

public

final

void

runonuithread

(runnable action)

else }

判斷當前執行緒是否是ui執行緒,如果不是,則呼叫handler的post方法,否則直接執行run方法。

非同步訊息機制的理解

1 looper準備工作場地 sthreadlocal 和工作用的道具 messagequeue 2 handler可以理解為 該機制的外掛程式,在activity中,因為activitythread已經定義了looper,所以直接例項化hander就可以使用了 3 messagequeue是系統中...

非同步訊息處理機制

借鑑 為什麼不能在子執行緒更新ui?1 ui是非執行緒安全的,主線程和子執行緒同時更新ui的話會導致錯誤,如ui錯亂之類的。2 ui更新是很耗效能的,更別說為了執行緒安全加鎖了,最簡單的方法就是更新ui的操作放到乙個執行緒中,即主線程 handler機制 looper 維持乙個thread物件以及m...

非同步訊息處理機制

因為android不允許在子執行緒中進行更新ui,非同步訊息處理機制來解決這個問題。android中的非同步訊息處理由4部分組成 message,handler,messagequeue和looper。message 傳遞訊息 handle 傳送,處理資訊 messagequeue 訊息隊裡,存放h...