-
在ViewRootImpl沒有實例化的時候是不會check是否是主線程,也就是說,在非UI線程中是可以更新UI的,但是為了線程安全的原因,系統(tǒng)會強(qiáng)制要求只能在主線程中更新UI(猜測)。之所以說沒有太大的意義是因為實際開發(fā)中是不會有這種情況的,谷歌官方也是說了只能在UI線程更新UI,這頂多算是一個BUG吧,看不懂的朋友們知道就行了,不用深究~ 非UI線程能否更新UI --->剛啟動的時候,立即在非UI線程更新->不報錯。 --->休眠2s鐘以后,更新——————>報錯 更新UI-->會調(diào)用checkForRelayout()方法 -->invalidate()方法-->invalidate(true)方法,關(guān)注viewParent-->ViewRootImpl是ViewParent的實現(xiàn)類 --->p.invalidateChild()-->查看ViewRootImpl.invalidateChild()-->checkThread()方法-->判斷UI線程是否是當(dāng)前線程,不想等拋出異常。 ViewRootImpl是onResume()方法才會創(chuàng)建。所以onCreate()方法中要延遲才可以。 handleResumeActivity()方法---》viewManager.addView()-->ViewRootImpl初始化。,關(guān)注viewParent-->ViewRootImpl是ViewParent的實現(xiàn)類 在非UI線程中是可以更新Ui的(在onCreate中創(chuàng)建新線程更新UI): 當(dāng)剛啟動Activity即onCreate里面此時onResume方法還沒有執(zhí)行的時候可以,因為在線程中更新UI時會調(diào)用ViewParent.invalidateChild()方法檢查當(dāng)前的Thread是否是UIThread,若為UIThread則可以更新(ViewParent是一個接口類,其實現(xiàn)是ViewRootImpl;invalidateChild()方法調(diào)用checkThread()方法來檢查線程是否為主線程)。ViewRootImp是在onResume方法中初始化的,所以只要在ViewRootImpl創(chuàng)建之前更新UI(在onCreate方法中創(chuàng)建線程并執(zhí)行,此時還沒有初始化ViewRootImp),就可以逃避掉checkThread()的檢查進(jìn)而更新UI。查看全部
-
主要是在HandlerThread里面創(chuàng)建一個Looper,和默認(rèn)的 handler 進(jìn)行關(guān)聯(lián)。 所有的handlerMessage()都是在子線程中調(diào)用。 我們可以使用 HandlerThread 模擬異步任務(wù)的操作,只需要在主線程中給子線程發(fā)送消息,讓子線程做耗時操作。 總之,HandlerThread可以處理耗時操作,例如下載網(wǎng)絡(luò)圖片、更新數(shù)據(jù)庫等等,可以在完全不占用主線程的情況下處理比較耗時的操作。從設(shè)計的角度來看,是比較方便快捷的。 因為如果自己想要實現(xiàn)異步任務(wù)機(jī)制,就需要考慮一些問題,例如要開啟線程、往異步任務(wù)中添加任務(wù),任務(wù)本身還要考慮存儲結(jié)構(gòu)、什么時候添加任務(wù)、什么時候移除任務(wù),以及任務(wù)如何傳遞、派發(fā)等等。比較麻煩。 而Android提供了HandlerThread方法,它是系統(tǒng)已經(jīng)將任務(wù)的發(fā)送、處理等都封裝好了,使用起來比較方便,我們只需調(diào)用 HandlerThread。查看全部
-
Handler是什么? Handler是Android提供的一套用來更新UI的機(jī)制,也是一套消息處理機(jī)制,可以通過它發(fā)送消息,也可以通過它處理消息。 所有Activity生命周期回調(diào)的方法,都是通過handler機(jī)制去發(fā)送消息的,然后根據(jù)不同的消息(message)做相應(yīng)的分支處理。例如發(fā)送一個消息給 Framework,告知需要調(diào)用onCreate()或onDestory()方法。實際上在 Framework 當(dāng)中,Activity的交互大部分都是用AMS(Activity Manager Service)做處理的。整個應(yīng)用程序的核心的一個類就是 Activity Thread,Activity Thread就是通過handler機(jī)制接收到 Activity Manager Service發(fā)送的有關(guān)Activity生命周期的管理的消息(比如啟動)。 為什么要使用Handler? Android在設(shè)計的時候,就封裝了一套消息的創(chuàng)建、傳遞、處理機(jī)制,如果不遵循這樣的機(jī)制,就沒有辦法更新UI信息,并且會拋出異常信息。這樣的機(jī)制便包含Handler機(jī)制。 我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,Android主線程是線程不安全的,也就是說,更新UI只能在主線程中更新,子線程中操作是危險的。這個時候,Handler就出現(xiàn)了。來解決這個復(fù)雜的問題 ,由于Handler運(yùn)行在主線程中(UI線程中),它與子線程可以通過Message對象來傳遞數(shù)據(jù), 這個時候,Handler就承擔(dān)著接受子線程傳過來的(子線程用sedMessage()方法傳遞)Message對象(里面包含數(shù)據(jù)),把這些消息放入主線程隊列中,配合主線程進(jìn)行更新UI。 Handler主要接受子線程發(fā)送的數(shù)據(jù),并用此數(shù)據(jù)配合主線程更新UI。 當(dāng)應(yīng)用程序啟動時,Android首先會開啟一個主線程 (也就是UI線程) ,主線程為管理界面中的UI控件,進(jìn)行事件分發(fā),比如說, 你要是點擊一個 Button ,Android會分發(fā)事件到Button上,來響應(yīng)你的操作。如果此時需要一個耗時的操作,例如: 聯(lián)網(wǎng)讀取數(shù)據(jù),或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現(xiàn)假死現(xiàn)象,如果5秒鐘還沒有完成的話,會收到Android系統(tǒng)的一個錯誤提示 "強(qiáng)制關(guān)閉"。查看全部
-
handler是android提供的用于更新UI的一套機(jī)制,也是一套用于消息處理的機(jī)制,我們可以通過它來發(fā)送和處理消息查看全部
-
handler是android為我們提供的一套用于更新UI查看全部
-
Handler是什么?查看全部
-
handler handlerMessage接受信息的方法 發(fā)送信息要實現(xiàn)Message方法 Looper.mylooper獲取一個looper looper.Loop循環(huán)looper Handler 負(fù)責(zé)發(fā)送信息 Looper 負(fù)責(zé)接受handler發(fā)送過來的信息 MessageQueue 存儲信息的容器查看全部
-
系統(tǒng)已為UI線程準(zhǔn)備好了looper和msgqueue。 這時候用戶在UI線程創(chuàng)建了handler對象并不會報錯。 接著子線程里調(diào)用post或者send方法,實際上就是往UI線程的msgqueque對象里enqueque一條msg。 而UI線程的looper一直在loop,所以當(dāng)msgqueque里新增了msg對象并觸發(fā)條件滿足后會調(diào)用msg里target的dispatchmsg方法。 實際上就是Handler父類的dispatchMsg方法。 緊接著handler父類再決定調(diào)用post過來的邏輯還是子類覆寫的handlemsg方法。查看全部
-
post 不用實現(xiàn)handlemsg 適用于簡單的處理邏輯的場合 使用場景較少 sendmsg 需要實現(xiàn)handlemsg 適用于需要傳遞線程間數(shù)據(jù)進(jìn)行處理的場合 使用場景較多查看全部
-
handler,looper,messagequeue,message,thread.學(xué)習(xí)了解之間關(guān)系,知道函數(shù)及使用查看全部
-
handler查看全部
-
handler查看全部
-
handler、looper、messagequeue、message四者可以這樣理解: handler:工人; looper:傳送帶移動的動力; messagequeue:傳送帶; message:傳送帶上面的產(chǎn)品。 工人(handler)把自己的產(chǎn)品(message)放在傳送帶(messagequeue)尾部,在動力(looper)作用下,傳送帶向前移動,最終產(chǎn)品到達(dá)傳送帶頭部,被取出來處理(handmessage())。 ----------------- 先要有個概念。 1、handler 消息處理器,負(fù)責(zé)處理消息。 2、Message 消息,包含消息id,被處理的對象。 3、MessageQueue 消息隊列,存放Handler發(fā)送過來的Message 4、looper 消息泵,不間斷的從MessageQueue消息隊列中抽取消息。 簡單的比喻looper就是水泵,MessageQueue儲水的池塘,Message就是水,Handler就是操作的人。查看全部
-
以下內(nèi)容來自大神筆記: handler、looper、messagequeue、message四者可以這樣理解: handler:工人; looper:傳送帶移動的動力; messagequeue:傳送帶; message:傳送帶上面的產(chǎn)品。 工人(handler)把自己的產(chǎn)品(message)放在傳送帶(messagequeue)尾部,在動力(looper)作用下,傳送帶向前移動,最終產(chǎn)品到達(dá)傳送帶頭部,被取出來處理(handmessage())。 ----------------- 先要有個概念。 1、handler 消息處理器,負(fù)責(zé)處理消息。 2、Message 消息,包含消息id,被處理的對象。 3、MessageQueue 消息隊列,存放Handler發(fā)送過來的Message 4、looper 消息泵,不間斷的從MessageQueue消息隊列中抽取消息。 簡單的比喻looper就是水泵,MessageQueue儲水的池塘,Message就是水,Handler就是操作的人。查看全部
-
Handler的原理是什么? 面試經(jīng)典問題:Looper、Handler、Message(或MessageQueue)三者間的關(guān)系? 一、Handler封裝了消息的發(fā)送(主要是將消息發(fā)送給誰(默認(rèn)是Handler自己),以及什么時候發(fā)送)。 Looper: 1.內(nèi)部包含一個消息隊列 MessageQueue,所有的 Handler 發(fā)送的消息都走向(加入)這個消息隊列。 2.Looper.Looper方法,就是一個死循環(huán),不斷地從 MessageQueue 取得消息,如果有消息就處理消息,沒有消息就阻塞。 二、MessageQueue MessageQueue 就是一個消息隊列,可以添加消息,并處理消息。 三、Handler 也很簡單,內(nèi)部會跟 Looper 進(jìn)行關(guān)聯(lián),也就是說,在 Handler 的內(nèi)部可以找到 Looper,找到了 Looper 也就找到了 Message。在 Handler 中發(fā)送消息,其實就是向 MessageQueue 隊列中發(fā)送消息。 總結(jié):Handler 負(fù)責(zé)發(fā)送消息,Looper 負(fù)責(zé)接收 Handler 發(fā)送的消息,并直接把消息回傳給 Handler 自己,MessageQueue就是一個存儲消息的容器。查看全部
舉報
0/150
提交
取消