Android 為什么主線程的looper 一直循環(huán)不會ANR

閱讀此文需要對handler原理有一定的了解程度渣叛。

Handler 原理和源碼

首先貼出來兩個知識點。

第一 java線程可以休眠

第二Android只有主線程可以更新UI

有人覺得這是傻子都知道的知識盯捌,那接下來說傻子可能不知道的知識

直接敘述

所有java的入口都是main方法 由虛擬機調(diào)用淳衙,Android 的也不例外,剛開始學習那會根本沒研究Android 從哪里開始執(zhí)行的饺著,現(xiàn)在我知道了告訴那些不知道的同學箫攀,不是從application。直接看源碼ActivityThread?


看到了嗎幼衰?看到了吧靴跛。

再來一個驚天的大冪冪


當main 方法執(zhí)行完畢之后,程序就會退出了渡嚣。

那不對啊和我們看到的不一樣啊梢睛,App啟動之后可以一直運行啊,怎么解釋识椰。

直接解釋绝葡,App一直運行這個是沒錯的,也就是說明main方法并沒有執(zhí)行完腹鹉,看代碼


activityThread的main方法

先看3藏畅,如果main方法執(zhí)行完到最后會拋一個異常,很明顯我們的App并沒有拋異常功咒,那就說明Main方法沒有執(zhí)行完愉阎。

那怎么才能保證不會執(zhí)行完畢呢绞蹦?

這個問題就需要思考了,如果讓我做榜旦,最先想到的就是開一個死循環(huán)坦辟,但是時間一長肯定就OOM了,

其實Android 也是這么做的? 章办,1處的代碼 里面不給大家看了 大概的邏輯內(nèi)容我文字帶過

創(chuàng)建一個唯一的Looper 對象锉走,然后綁定一個messageQueue隊列 。(不懂的可以去看handler 詳解)

然后看2 代碼里邊就是開啟了Looper循環(huán)藕届,一個死循環(huán)無限的從消息隊列中去取消息(handler源碼)挪蹭。

這樣的話我們的Main方法就卡在這里了,就不會執(zhí)行完休偶,程序也就是我們看到那樣梁厉,一直在運行。

剛才我說了要是咱們寫個死循環(huán)那估計領導就得找我們談談理想了踏兜,時間一長就OOM了词顾,那為什么Android 可以這么搞呢,簡單解釋一下我也不懂也不深究碱妆,linux層去實現(xiàn)的肉盹,阻塞式循環(huán),也就是有消息了就去執(zhí)行消息疹尾,沒有消息之后主線程就會休眠上忍,前邊說過了 java線程是允許休眠的(有興趣的朋友可以去單獨深究一下)

到這里了 如果你明白了這一點,就說明我的敘述能力還是可以的(如果沒懂那就多看兩遍纳本,看到懂為止? 哈哈)

主線程在main方法中開了一個阻塞式死循環(huán)窍蓝,保證我們的程序不會退出。

問題2來了?

說是死循環(huán)繁成,但是我們的App可不是死的吓笙,使能夠接受交互的。

這里還是handler機制的功勞(不懂的可以去看handler 機制)巾腕,當我們一個事件比如說一個點擊面睛、長按、滑動祠墅,都會通過handler 把這個事件封裝成一個message 消息侮穿,并且放到Looper的死循環(huán)隊列當中歌径,這個時候的主線程就會被喚醒毁嗦,然后對Message進行分發(fā) ,這個時候事件已經(jīng)被分配到了主線程當中回铛,然后具體去執(zhí)行狗准,比如toast等等克锣。這就是一個完整的事件處理流程。

那么問題來了 我們正常點擊的速度是肯定沒有程序執(zhí)行快的腔长,所以說不會有任何問題袭祟,但是如果一個點擊事件當中執(zhí)行了耗時操作,看下面代碼


? 這個點擊了 會ANR嗎捞附?答案是不一定巾乳,

第一種情況,如果只點擊了一次鸟召,主線程休眠十秒胆绊,沒有問題,十秒之后主線程執(zhí)行完畢欧募,繼續(xù)阻塞式休眠压状。

第二種情況,如果連續(xù)點擊了多次跟继,多個事件放到Looper 對象的MessageQueue當中 种冬,第一個事件去執(zhí)行,主線程休眠十秒舔糖,然后第二個事件分發(fā)過來的時候娱两,主線程還在sleep,這個時候我們的第二個事件就一直得不到執(zhí)行金吗,超過閥值就會ANR谷婆。

ANR 的原因 因為Looper對象MessageQueue隊列中的事件沒有能夠得到及時執(zhí)行。

閥值

按鍵事件 5s 辽聊,broadcast 10s纪挎、service ANR超時的定義在ActiveServices.java中,前臺service無響應的超時時間為20秒跟匆,后臺service為200秒

回到主題异袄,Android 主線程looper 一直循環(huán)不會ANR

兩個方面回答? 第一,死循環(huán)不是造成ANR的必然原因 玛臂,ANR是因為消息隊列當中的事件沒有得到及時的處理造成的烤蜕。(但是我們寫個死循環(huán) 基本上就會造成ANR,原因就是主線程一直在這里循環(huán) 迹冤,后面的事件沒有的到及時處理讽营。 )

第二 主線程的Looper 循環(huán) 不會ANR最多就是OOM,為什么不會OOM上邊解釋了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泡徙,一起剝皮案震驚了整個濱河市橱鹏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖莉兰,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑围,死亡現(xiàn)場離奇詭異,居然都是意外死亡糖荒,警方通過查閱死者的電腦和手機杉辙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捶朵,“玉大人蜘矢,你說我怎么就攤上這事∽劭矗” “怎么了硼端?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寓搬。 經(jīng)常有香客問我珍昨,道長,這世上最難降的妖魔是什么句喷? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任镣典,我火速辦了婚禮,結(jié)果婚禮上唾琼,老公的妹妹穿的比我還像新娘兄春。我一直安慰自己,他們只是感情好锡溯,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布赶舆。 她就那樣靜靜地躺著,像睡著了一般祭饭。 火紅的嫁衣襯著肌膚如雪芜茵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天倡蝙,我揣著相機與錄音九串,去河邊找鬼。 笑死寺鸥,一個胖子當著我的面吹牛猪钮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胆建,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烤低,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了笆载?” 一聲冷哼從身側(cè)響起扑馁,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涯呻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后檐蚜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魄懂,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡沿侈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年闯第,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缀拭。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡咳短,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛛淋,到底是詐尸還是另有隱情咙好,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布褐荷,位于F島的核電站勾效,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏叛甫。R本人自食惡果不足惜层宫,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望其监。 院中可真熱鬧萌腿,春花似錦、人聲如沸抖苦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锌历。三九已至贮庞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間究西,已是汗流浹背贸伐。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怔揩,地道東北人捉邢。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像商膊,于是被迫代替她去往敵國和親伏伐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容