日更(十八)-Android-Looper是個什麼東西
瞎扯
昨天寫了bus的生產者與消費者.
今天就寫寫looper
為什麼不和handler一起寫呢?因為懶.
Looper
loop翻譯一下,迴路,迴圈
大致就是迴圈的意思.
android裡也一樣.一個可以無限的死迴圈
其實大部分人應該都知道looper是個迴圈,不斷的取訊息,然後呼叫handler處理.
啟動過程:
翻一下Handler的原始碼
建構函式.裡的一段
mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()"); }
handler必須持有一個Looper物件
Looper物件怎麼來?
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } /** * Return the Looper object associated with the current thread.Returns * null if the calling thread is not associated with a Looper. */ public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
Looper.prepare()
應該很熟悉吧.
再來一段程式碼,子執行緒中建立Handler:
public void test() { new Thread(){ @Override public void run() { super.run(); Looper.prepare(); Handler handler = new Handler(); Looper.loop(); } }.start(); }
經歷不深的人,看著這一段,肯定是懵的.
為什麼調下 Looper.prepare()
就行了.怎麼跟handler聯絡上的.
調 Looper.loop();
的幹嘛?
Looper怎麼跟handerl關聯上的.明天再寫.哈哈
今天就寫為什麼要調 Looper.loop();
寫份虛擬碼你應該就明白了.
public void test2() { new Thread() { @Override public void run() { super.run(); Looper looper = new Looper();//建立Looper, Handler handler = new Handler(looper);//handler繫結looper looper.loop();//looper開啟迴圈 } }.start(); } public class Looper { public Looper prepare() { return new Looper(); } public void loop() { for (; ; ) { //msg.target.dispatchMessage(msg); handler.dispatchMessage(msg);//死迴圈,呼叫handler的回撥處理結果. } } }
去掉那些複雜的程式碼.
其本質差不多就這樣,略過了 MessageQueue
.
MessageQueue
就是個有序佇列,其實沒啥好講的.一個集合而已.
looper.loop();為什麼要線上程的最後呼叫?
因為死迴圈啊...不在最後呼叫在哪呼叫.
還有為了讓這個執行緒不結束啊.
不信可以試試在 loop()
後面再寫程式碼.你看會不會往下走- -
把方法裡的內容展開一下
new Thread() { @Override public void run() { super.run(); Looper looper = new Looper(); Handler handler = new Handler(looper); for (; ; ) { //msg.target.dispatchMessage(msg); handler.dispatchMessage(msg); } //如果不手動呼叫,looper怎麼工作呢, 並且保證執行線上程的最後面- - //可以試試,不呼叫loop(), handler會不會的回撥會不會走. } }.start();
看看ams中如何建立的主執行緒的handler,looper

image.png
這個 ServiceThread
是什麼鬼

image.png
是不是我前面說的那麼回事.哈哈

image.png
總結:
AMS,啟動了主執行緒. 然後我們寫的所有activity,fragment之類的程式碼,什麼onCreate,onStart裡的程式碼.
其實都相當於,執行在Looper.loop()裡面.通過handler傳送訊息.處理訊息在不停的呼叫.方法調方法這樣不停的.如果你不停的debug下一行,就會發現跑到Looper裡面去了.就是這麼個道理.
所以,當我們某個UI更新操作邏輯過於複雜,就會出現卡死的情況.
onstart,onparse等生命週期裡面邏輯太複雜也會造成ANR.因為主執行緒走不下去了.肯定沒法響應啊.
主執行緒的Looper退出迴圈,意味著,主執行緒結束,程式退出.
您的喜歡與回覆是我最大的動力-_-
交流群:493180098