打開應(yīng)用的時(shí)候都是創(chuàng)建一個(gè)進(jìn)程但汞,主線程采用死循環(huán)保證程序一直執(zhí)行下去壤圃,這種模型是“以事件為驅(qū)動(dòng)”軟件系統(tǒng)的必然結(jié)果捌袜,幾乎存在與任何操作系統(tǒng)和編程語言中。ActivityThread主循環(huán)的消息來自于當(dāng)前進(jìn)程和通過IPC機(jī)制投遞來過的消息(觸摸貌夕、按鍵事件)律歼,通過死循環(huán)looper.loop一直獲取消息,有消息都執(zhí)行我們生命周期方法或者頁面交互啡专,無消息CPU休眠不消耗資源险毁,這都是apk能“動(dòng)起來”根本原因。這些消息告知主線程要執(zhí)行onCreate\onStart\onResume等及其如果在執(zhí)行這些方法時(shí)候消耗時(shí)間過長會(huì)導(dǎo)致ANR或者頁面不流暢们童,所以我們是根據(jù)消息來回饋頁面交互畔况,從這里可以說明looper的死循環(huán)跟主線程卡死不是一回事。
線程與進(jìn)程之間關(guān)系:對(duì)于liux來說區(qū)別在于是否共享資源慧库,對(duì)于CPU來說都是一段可執(zhí)行的代碼跷跪,CPU采用CFS調(diào)度算法,保證每個(gè)task公平享有CPU時(shí)間片齐板。
采用死循環(huán):線程都是一段可執(zhí)行的代碼吵瞻,執(zhí)行完了后線程的生命周期該終止了,如果要保證一直運(yùn)行覆积,都要采用死循環(huán)听皿。
交互產(chǎn)生:回調(diào)onCreate\onStart\onResume等方法操作時(shí)間過長導(dǎo)致掉幀發(fā)生ANR,looper.loop本身不會(huì)導(dǎo)致應(yīng)用卡死宽档∥疽蹋回調(diào)生命周期方法,涉及到ActivityThread里面的ApplicationThread用于接收跨進(jìn)程系統(tǒng)服務(wù)AMS發(fā)送過來的事件吗冤,然后ApplicationThread使用handler發(fā)送消息到主線程管理類ActivityThread執(zhí)行相應(yīng)的生命周期又厉。通過發(fā)送消息來控制生命周期,所以頁面的交互靠底層發(fā)送的消息到主線程來進(jìn)行頁面的變化椎瘟。
消息死循環(huán)和消耗:我們先了解下Loop死循環(huán)原理覆致,當(dāng)在MessageQueue沒有消息或者有延遲執(zhí)行的消息時(shí)候,便會(huì)阻塞在MessageQueue.next方法里的nativePollOnce代碼里面肺蔚。這個(gè)時(shí)候線程都會(huì)釋放CPU資源進(jìn)入休眠狀態(tài)煌妈,直到下一個(gè)消息到達(dá)或者事務(wù)發(fā)生,通過往pipe管道寫端寫數(shù)據(jù)作喚醒線程工作宣羊。這個(gè)采用了epoll機(jī)制璧诵,IO多路復(fù)用機(jī)制,同時(shí)監(jiān)控多個(gè)描述符仇冯,有描述符就緒(讀寫操作)之宿,立刻通知相應(yīng)的用程序進(jìn)行讀寫操作,本質(zhì)IO同步苛坚,讀寫阻塞比被。因?yàn)樗姥h(huán)時(shí)候CPU處于休眠狀態(tài),所以并不會(huì)耗費(fèi)大量資源色难。