Handler、Message的简单使用
public class
Handler
extends Object| java.lang.Object | |
| ???? | android.os.Handler |
Class Overview
A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
?
public final boolean sendMessage(Message msg)Added inAPI level 1
Pushes a message onto the end of the message queue after all pending messages before the current time. It will be received inhandleMessage(Message), in the thread attached to this handler.
Returns
- Returns true if the message was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.
public final class
2、
Looper
extends Object| java.lang.Object | |
| ???? | android.os.Looper |
Class Overview
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, callprepare() in the thread that is to run the loop, and thenloop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.?
Looper時時刻刻監視著MessageQueue,是每個線程中的MessageQueue管家,每個線程中只有一個Looper,調用其loop()方法就會進入到一個無限循環中,每當發現MessageQueue中存在一條消息,就會把它取出,送到Handler中的handleMessage()中。 public final class 3、MessageQueue
extends Object| java.lang.Object | |
| ???? | android.os.MessageQueue |
4、 public final class
Message
extends Objectimplements Parcelable
| java.lang.Object | |
| ???? | android.os.Message |
Class Overview
Defines a message containing a description and arbitrary data object that can be sent to aHandler. This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.?
//Message android.os.Message.obtain(Handler h, int what) Message mMessage = Message.obtain(mHandler, UPDATE_TEXT);Message是在線程之間傳遞消息,它可以在內部攜帶少量信息,如what字段、arg1、arg2來攜帶一些整型數據、obj攜帶Object對象,用于在不同線程間交換數據。異步消息處理的整個流程:
首先需要在主線程中創建一個Handler對象,并重寫handleMessage()方法; 然后,當子線程中需要UI操作時,就創建一個Message對象,并通過Handler將消息發送出去; 之后這條消息會被添加到MessageQueue隊列中,等待被處理,期間Looper會一直嘗試從MessageQueue中取出待處理消息,最后分發到Handler的handleMessage()方法中。由于Handler是在主線程中創建的,因此handleMessage()中的代碼也會在主線程中處理。
MeloDev的Message游歷:
Message
在邊境X(子線程)服役的士兵Message慵懶的躺在一個人數為50(線程中最大數量)的軍營(Message池)中。不料這時突然接到上司的obtain()命令,讓它去首都(主線程)告訴中央領導一些神秘代碼。小mMessage慌亂地整理下衣角和帽子,帶上信封,準備出發。上司讓士兵mMessage收拾完畢等待一個神秘人電話,并囑咐他:到了首都之后,0是這次的暗號。Message mMessage = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("key","這里一切安全"); mMessage.what = 0; mMessage.obj = bundle;通常會用obtain()方法創建Message,如果消息池中有Message則取出,沒有則創建,這樣防止對象重復創建,節省資源。 obtain()方法源碼: /*** Return a new Message instance from the global pool. Allows us to* avoid allocating new objects in many cases.*/public static Message obtain() {synchronized (sPoolSync) {if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;sPoolSize--;return m;}}return new Message();}
“鈴鈴鈴……”,小mMessage接到一個店換,"我叫Handler,來此Activity大本營,是你這次任務的接收者,一會我會帶你去首都的消息中心去報道。"
Handler:
來此Activity大本營的Handler部門是整個消息機制的核心部門,部門里有很多個Handler,這次協助小mMessage的叫mHandler. mHandler = new Handler(){public void handleMessage(Message msg){ //int android.os.Message.what //User-defined message code so that the recipient can identify what this message is about.}};Handler屬于Activity,創建任何一個Handler都屬于重寫了Activity的Handler。
在Handler的構造中,默認完成了對當前線程Looper的綁定。 public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;}
通過Looper.myLooper()方法獲得當前線程保存的Looper實例,通過Looper.mQueue()獲得MessageQueue實例,
| static Looper | myLooper()Return the Looper object associated with the current thread. |
| static MessageQueue | myQueue()Return the MessageQueue object associated with the current thread. |
mHandler神情驕傲的對小mMessage說:我已經跟首都的消息中心打好了招呼,準備接收你了,現在有兩種車“send”和“post”你想坐哪輛都可以,不過要根據你上司的命令選擇對應的型號哦~
post、send:
| final boolean | post(Runnable r)Causes the Runnable r to be added to the message queue. |
| final boolean | postAtFrontOfQueue(Runnable r)Posts a message to an object that implements Runnable. |
| final boolean | postAtTime(Runnable r,Object token, long uptimeMillis)Causes the Runnable r to be added to the message queue, to be run at a specific time given byuptimeMillis. |
| final boolean | postAtTime(Runnable r, long uptimeMillis)Causes the Runnable r to be added to the message queue, to be run at a specific time given byuptimeMillis. |
| final boolean | postDelayed(Runnable r, long delayMillis)Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses |
| final boolean | sendEmptyMessage(int what)Sends a Message containing only the what value. |
| final boolean | sendEmptyMessageAtTime(int what, long uptimeMillis)Sends a Message containing only the what value, to be delivered at a specific time. |
| final boolean | sendEmptyMessageDelayed(int what, long delayMillis)Sends a Message containing only the what value, to be delivered after the specified amount of time elapses. |
| final boolean | sendMessage(Message msg)Pushes a message onto the end of the message queue after all pending messages before the current time. |
| final boolean | sendMessageAtFrontOfQueue(Message msg)Enqueue a message at the front of the message queue, to be processed on the next iteration of the message loop. |
| boolean | sendMessageAtTime(Message msg, long uptimeMillis)Enqueue a message into the message queue after all pending messages before the absolute time (in milliseconds)uptimeMillis. |
| final boolean | sendMessageDelayed(Message msg, long delayMillis)Enqueue a message into the message queue after all pending messages before (current time + delayMillis). |
| String | toString() |
分析源碼,post方法也是在使用send類在發送消息,除了sendMessageAtFrontOfQueue()外,其余send方法都經過層層包裝走到sendMessageAtTime()中。 這時小mMessage和mHandler上了sendMessage的車,行駛在一條叫enqueueMessage的高速公路上進入MessageQueue。將Message按時間排序,放入MessageQueue中。其中mMessage.target = this,是保證每個發送Message的Handler也能處理這個Message。mHandler向小mMessage說,其實你的消息到時候也是我處理的,不過現在還不是時候,因為我很忙。
Looper
路上時間,mHandler為小mMessage熱心介紹著MessageQueue和Looper?!霸诿總€駐扎地(線程)中只有一個MessageQueue和一個Looper,他們兩個是相愛相殺,同生共死的好朋友,Looper是個跑不死的郵差,一直負責取出MessageQueue中的Message”。 "不過通常只有首都(主線程)的Looper和MessageQueue是創建好的,其他地方需要我們人為創建"。 Looper提供prepare()方法來創建Looper。重復創建會拋出異常,也就是說每個線程只能有一個looper。
Looper.prepare();
| static void | prepareMainLooper()Initialize the current thread as a looper, marking it as an application's main looper. |
Looper的構造方法中,創建了和他一一對應的MessageQueueprivate Looper(boolean quitAllowed){mQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread(); }
在Android中ActivityThread的main方法是程序入口,主線程的Looper和MessageQueue就是在此刻創建。
mHandler和小mMessage來到了MessageQueue中,進入隊列之前,門衛仔細給小mMessage貼上以下標簽:“mHandler負責帶入”、“處理時間為0ms”并告訴小mMessage一定要按時間順序排隊。進入隊伍中,Looper正不辭辛勞的將一個個跟小mMessage一樣的士兵帶走。
public static void loop()
Run the message queue in this thread. Be sure to callquit() to end the loop. ?
loop()方法有一個for死循環,不斷調用queue.next()方法,在消息隊列中取出Message。并在Message中取出target,這個target就是發送消息的mHandler調用它的dispatchMessage()方法。首都的MessageQueue中心雖然message很多,但大家都按時間排著隊,輪到mMessage了,Looper看了小mMessage的標簽,對他說:“喔,又是mHandler帶來的啊,那把你交給他處理了?!膘话驳男Message看到了一個熟悉的身影,mHandler,可能是接觸太多Message,為了讓mHandler想起自己,mMessage說出了上司教他的暗號0。
public void dispatchMessage(Message msg){ if(msg.callback != null){ handleCallback.handleMessage(msg); }else{ if(mCallback != null){ if(mCallback.handleMessage(msg)){ return;} } handleMessage(msg); } }
dispatchMessage()方法:若mCallback不為空,則調用mCallback的handleMessage();否則,直接調用Handler的handleMessage()方法,并將消息對象作為參數傳遞過去。在handleMessage()方法中,小mMessage出色的完成了任務。
簡單使用代碼在:https://github.com/HiSunny/ComeOnHandler.git
Thanks to ?MeloDev、stromzhang 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的Handler、Message的简单使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wps2019专业版激活码序列号wps2
- 下一篇: 微信游戏中心电脑版(微信游戏首页)