-
Handler的post(Runnable)用法。查看全部
-
為什么用Handler.查看全部
-
handler是什么,以及作用。查看全部
-
非UI線程能否更新UI --->剛啟動的時候,立即在非UI線程更新->不報錯。 --->休眠2s鐘以后,更新——————>報錯 更新UI-->會調用checkForRelayout()方法 -->invalidate()方法-->invalidate(true)方法,關注viewParent-->ViewRootImpl是ViewParent的實現類查看全部
-
更新UI的4種方式: 1.通過Handle的post方法(); 2.調用Handle.sendMessage()方法;傳統的方法 3.重寫Activity中的runOnUIThread方法更新; 4.調用View自身的post(Runnable run)方法更新;查看全部
-
HandlerThread的用處: 創建Handler的時候可以指定Looper,所以這個Looper對象可以是別的線程創建的。所以Handler中MessageQueue的輪詢不一定非要是創建Handler的線程進行,還可以別的線程進行。但是進行的時候需要我們保證傳入的looper對象已經被別的線程創建好了,否則會出現空指針異常。這個時候我們就需要使用HandlerThread這個類來創建這個Looper了。 http://developer.android.com/reference/android/os/HandlerThread.html HandlerThread的介紹: Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.查看全部
-
創建Handler的時候可以指定Looper,所以這個Looper對象可以是別的線程創建的。所以Handler中MessageQueue的輪詢不一定非要是創建Handler的線程進行,還可以別的線程進行。查看全部
-
在主線程中創建的Handler的handleMessage()方法不要寫耗時的操作,否則會導致UI卡死,因為這個handleMessage()方法是在UI線程中調用的。查看全部
-
創建一個與線程相關的Handler: 1. 在線程中通過Looper.prepare()方法創建一個與線程相關的Looper對象; 2. 在線程中通過Handler的new關鍵字,創建一個Handler對象,這個對象在創建的時候會關聯上1中創建的Looper對象 3. 調用Looper對象的loop()方法去輪詢它的MessageQueue 4. 通過其他的線程拿到這個線程的Handler對象之后調用sendMessage()之后,在這個線程中就可以進行Message的處理了。 我們一般是在主線程中創建Handler對象,在主線程中處理Message,在子線程中調用這個Handler對象的sendMessage()來發送message。所以Handler是在哪個線程創建就有哪個線程處理Message和輪詢,而由別的線程負責給這個Handler發送Message。查看全部
-
Handler sendMessage圖解查看全部
-
當我們將Handler在主線程(UI線程)中創建的時候,Handler對象會關聯一個Looper對象,這個Looper對象不是我們創建的,是早就由ActivityThread的main線程(ActivityThread的main線程就是負責創建和更新UI和輪詢消息的,和我們開發window應用一樣,它有個大循環在里面,在這個大循環中,Looper對象會不斷的去調用loop()方法進行消息輪詢)創建好了的,而這個Looper對象里面就有就有它的MessageQueue對象(其實就是一個以linked list形式保存Message對象的數據結構)。查看全部
-
總結:Handler負責發送消息和處理消息;Looper負責接收消息和輪詢消息,并且將消息轉發給Handler自己,由Handler自己在不同的線程中處理消息;MessageQueue就是一個消息的容器,Looper內部包含了MessageQueue對象的引用,就是通過這個容器,Looper才能完成對消息的輪詢(通過loop()方法)。查看全部
-
Handler和Looper和MessageQueue之間的關系:Handler對象中既有Looper對象的引用也有MessageQueue對象的引用,其中MessageQueue是通過它的Looper對象的一個mQueue屬性獲取的,而Looper的對象是創建Handler的線程創建的(創建Looper對象需要調用它的靜態方法prepare()創建,不能直接new出來),Looper的對象是通過當前創建Handler的線程創建的,并且要保證這個線程要去調用Looper對象的loop()方法進行Message的輪詢(在loop()內部會調用一些native的方法完成本地的消息輪詢),如果要退出輪詢,可以調用Looper對象的quit()方法。UI線程(主線程)已經幫我們做好了這一切,所以,如果我們在主線程中創建Handler,那么就是由主線程自動幫我們去輪詢我們的MessageQueue,所以我們在子線程中調用Handler對象的post(),sendMessage(),才能在主線程(UI線程)中處理我們的Message,而且才能在主線程(UI線程)中更新我們的UI。 其實post(),postDelayed(), sendMessage(), sendMessageDelayed() 這四個方法本質都是調用的sendMessageAtTime()這個方法,只是post對runnable對象進行了包裝,包裝成了Message對象,而這個Message對象的callback就是runnable,最后我們在選擇Message處理方法的時候,優先看這個Message對象有沒有callback對象,如果有,就調用這個callback對象,然后再看整個handler對象有沒有callback對象,如果有,就調用這個callback對象的handleMessage()方法處理Message對象,如果沒有則調用handler對象本身的handleMessage方法處理Message,所以Message的處理是有優先級的。查看全部
-
為什么Android要設計只能通過UI線程去更新UI呢?查看全部
-
1、使用Handler在子線程中向ui線程發送一個消息進行UI的更新; 2、創建一個Message; Message msg = new Message(); msg.arg1=88; 3、handler.sendMessage(msg); // 最終導致同一個handler對象的handleMessage()方法被創建Handler對象的線程(一般在主線程中創建)回調,然會這個傳入的msg會被當成參數傳給handleMessage()方法的。這個時候我們就可以對Message對象做一些處理了,而且這個時候我們所處的線程一般就在UI線程中了,所以這個時候我們更新UI就沒有問題了。 msg.obj=xxx; 可以傳遞一個對象; 4、復用系統的message對象 Message msg = handler.obtainMessage(); // or Message.obtain(); msg.sendtoTarget(); 也可以發送到Handler對Message進行處理 handler.removeCallbacks(Runnable r); 如前面所說,我們除了在Handler對象的handleMessage()方法中處理Message對象,還可以在Handler對象創建的時候傳入一個Callback對象,用這個Callback對象來處理Message對象;注意:callback接口中handleMessage(Message msg)中若截獲則一定返回true; 這個callback看起來不錯喲查看全部
舉報
0/150
提交
取消