【Android面試知識點系列】Looper相關
Looper是一個面試中經常被用來問的知識點,我這裡也只是總結一下通過看Looper原始碼可能在面試中問到的知識點,還是推薦大家多看原始碼。
Looper在Handler機制中,就像是一個傳送帶的電動機,它驅動著傳送帶(MessageQueue)不斷的運輸貨物(message),handler類似於往傳送帶上面放置訊息的機械手臂。不知道這個比喻是否恰當。
預設執行緒中是否存在Looper(非主執行緒)?
否,預設執行緒中不存在Looper,只有在呼叫Looper.prepare()的時候才會建立關聯的Looper物件。呼叫Looper.loop()方法以後,如果還有程式碼,是否會執行?為什麼?
否,因為Looper.loop()方法體內是一個死迴圈,一直在處理與之關聯的messagequeue中的messageLooper.prepare()方法是如何建立Looper物件的。
首先會呼叫ThreadLocal.get方法判斷當前執行緒是否已經存在Looper物件,如果有會丟擲異常“Only one Looper may be created per thread”,如果不存在,則new一個Looper,並呼叫sThreadLocal.set方法。關於ThreadLocal也是一個經常考察的知識點,可以自己複習,後續我也會寫。主執行緒什麼時候建立的Looper?
在ActvityThread的main方法中,會呼叫Looper.prepareMainLooper()每一個應用的開始方法都是在一個ActivityThread中呼叫,負責四大元件以及其他操作的排程,具體以後也會單獨寫文章。Looper與MessageQueue的關係。
在Looper.prepare的時候,就會new一個Looper,而在Looper的構造方法中,會new一個MessageQueue的物件,MessageQueue主要就是用來存放待處理的message,在Handler中會通過呼叫looper的messagequeue來存放message。如何讓Looper中MessageQueue的所有訊息停止處理?而不是清除所有的訊息。
Looper.postSyncBarrier,有一個比較常用的場景,就是ViewRootImpl裡面只要是重新整理UI的時候,基本都會呼叫該方法,否則訊息一直被處理,就會導致介面重新整理異常。不過要注意的,等完成相關操作以後一定要呼叫removeSyncBarrier(int)如何終止Looper?
有兩個方法,一個是quit(),一個是quitSafely(),quit方法會立即停止loop方法,就算現在messageQueque中還有未處理的message,一樣不再處理。這樣有些不安全,還是建議大家使用後者,呼叫quitSafely(),會在處理完所有messageQueue中的已有訊息後終止,而handler再次sendMessage就會返回false;