2020-02-27 (線程+進(jìn)程)相關(guān)

Q(1):Handler中有Loop死循環(huán),為什么沒有阻塞主線程?
A:對于線程即是一段可執(zhí)行的代碼,當(dāng)可執(zhí)行代碼執(zhí)行完成后,線程生命周期便該終止了,線程退出。對于主線程,不希望被殺死,就要保持一只運(yùn)行狀態(tài),死循環(huán)便能保證不會(huì)被退 出。然而looper.loop本身不會(huì)導(dǎo)致應(yīng)用卡死, 真正會(huì)卡死主線程的操作的是,在一些回調(diào)方法 中如下方法:onCreate/onStart/onResume 等這些方法中操作時(shí)間過長,會(huì)導(dǎo)致掉楨,才導(dǎo)致ANR;

Q ( 2 ): 主線程的死循環(huán)一直運(yùn)行是不是特別消耗CPU資源呢?
A:其實(shí)不然,簡單說就是在主線程的MessageQueue沒有消息時(shí),便阻塞在loop的queue.next()方法里,此時(shí)主線程會(huì)釋放CPU資源進(jìn)入休眠狀態(tài),直到下個(gè)消息到達(dá)或者有事務(wù)發(fā)生,通過往pipe管道寫端寫入數(shù)據(jù)來喚醒主線程工作。這里采用的epoll機(jī)制,是一種IO多路復(fù)用機(jī)制,可以同時(shí)監(jiān)控多個(gè)描述符,當(dāng)某個(gè)描述符就緒(讀或?qū)懢途w),則立刻通知相應(yīng)程序進(jìn)行讀或?qū)懖僮?,本質(zhì)同步I/O,即讀寫是阻塞的。 所以說,主線程大多數(shù)時(shí)候都是處于休眠狀態(tài),并不會(huì)消耗大量CPU資源。

Q (3): 主線程的消息循環(huán)機(jī)制是什么?
A: Activity的生命周期都是依靠主線程的Looper.loop,當(dāng)收到不同Message時(shí)則采用相應(yīng)措施;比如收到msg=H.LAUNCH_ACTIVITY,則調(diào)用ActivityThread.handleLaunchActivity()方法,最終會(huì)通過反射機(jī)制,創(chuàng)建Activity實(shí)例,然后再執(zhí)行Activity.onCreate()等方法;再比如收到msg=H.PAUSE_ACTIVITY,則調(diào)用ActivityThread.handlePauseActivity()方法,最終會(huì)執(zhí)行Activity.onPause()等方法。

Q(4) 主線程的消息又是哪來的呢?
A: 當(dāng)然是App進(jìn)程中的其他線程通過Handler發(fā)送給主線程;
1: system_server進(jìn)程:
system_server進(jìn)程是系統(tǒng)進(jìn)程,java framework框架的核心載體,里面運(yùn)行 了大量的系統(tǒng)服務(wù),比如這里提供ApplicationThreadProxy(簡稱ATP), ActivityManagerService(簡稱AMS),這個(gè)兩個(gè)服務(wù)都運(yùn)行在system_server進(jìn)程的不同線程中,由于ATP和AMS都是基于IBinder接口,都是binder線程,binder線程的創(chuàng)建與銷毀都是由binder驅(qū)動(dòng)來決定的。
2: App進(jìn)程:
App進(jìn)程則是我們常說的應(yīng)用程序,主線程主要負(fù)責(zé)Activity/Service等組件的生命周期以及UI相關(guān)操作都運(yùn)行在這個(gè)線程; 另外,每個(gè)App進(jìn)程中至少會(huì)有兩個(gè)binder線程 ApplicationThread(簡稱AT)和ActivityManagerProxy(簡稱AMP),除了圖中畫的線程,其中還有很多線程。

Q(5)Binder 是啥 ?
A: Binder用于不同進(jìn)程之間通信,由一個(gè)進(jìn)程的Binder客戶端向另一個(gè)進(jìn)程的服務(wù)端發(fā)送事務(wù),比如圖中線程2向線程4發(fā)送事務(wù);而handler用于同一個(gè)進(jìn)程中不同線程的通信.

(備注):
ActivityThread的main方法主要就是做消息循環(huán),一旦退出消息循環(huán),那么你的程序也就可以退出了。從消息隊(duì)列中取消息可能會(huì)阻塞,取到消息會(huì)做出相應(yīng)的處理。如果某個(gè)消息處理時(shí)間過長,就可能會(huì)影響UI線程的刷新速率,造成卡頓的現(xiàn)象。

Android藝術(shù)開發(fā)探索中寫到:
ActivityThread通過ApplicationThread和AMS進(jìn)行進(jìn)程間通訊,AMS以進(jìn)程間通信的方式完成ActivityThread的請求后會(huì)回調(diào)ApplicationThread中的Binder方法,然后ApplicationThread會(huì)向H發(fā)送消息,H收到消息后會(huì)將ApplicationThread中的邏輯切換到ActivityThread中去執(zhí)行,即切換到主線程中去執(zhí)行,這個(gè)過程就是。主線程的消息循環(huán)模型。

Q(6) ActivityThread 的動(dòng)力是什么?
A: 進(jìn)程 每個(gè)app運(yùn)行時(shí)前首先創(chuàng)建一個(gè)進(jìn)程,該進(jìn)程是由Zygote fork出來的,用于承載App上運(yùn)行的各種Activity/Service等組件。進(jìn)程對于上層應(yīng)用來說是完全透明的,這也是google有意為之,讓App程序都是運(yùn)行在Android Runtime。大多數(shù)情況一個(gè)App就運(yùn)行在一個(gè)進(jìn)程中,除非在AndroidManifest.xml中配置Android:process屬性,或通過native代碼fork進(jìn)程。
線程 線程對應(yīng)用來說非常常見,比如每次new Thread().start都會(huì)創(chuàng)建一個(gè)新的線程。該線程與App所在進(jìn)程之間資源共享,從Linux角度來說進(jìn)程與線程除了是否共享資源外,并沒有本質(zhì)的區(qū)別,都是一個(gè)task_struct結(jié)構(gòu)體,在CPU看來進(jìn)程或線程無非就是一段可執(zhí)行的代碼,CPU采用CFS調(diào)度算法,保證每個(gè)task都盡可能公平的享有CPU時(shí)間片。

Q(7) Handler 是如何能夠線程切換?
A: 線程間是共享資源的,所以Handler處理不同線程問題就只要注意異步情況即可。
/**** Handler創(chuàng)建的時(shí)候會(huì)采用當(dāng)前線程的Looper來構(gòu)造消息循環(huán)系統(tǒng),Looper在哪個(gè)線程創(chuàng)建,就跟哪個(gè)線程綁定,并且Handler是在他關(guān)聯(lián)的Looper對應(yīng)的線程中處理消息的****/.
注意:①線程是默認(rèn)沒有Looper的,如果需要使用Handler,就必須為線程創(chuàng)建Looper。我們經(jīng)常提到的主線程,也叫UI線程,它就是ActivityThread,②ActivityThread被創(chuàng)建時(shí)就會(huì)初始化Looper,這也是在主線程中默認(rèn)可以使用Handler的原因。

Q(7-1):系統(tǒng)為什么不允許在子線程中訪問UI?
A(7-1):摘自《Android開發(fā)藝術(shù)探索》) 這是因?yàn)锳ndroid的UI控件不是線程安全的,如果在多線程中并發(fā)訪問可能會(huì)導(dǎo)致UI控件處于不可預(yù)期的狀態(tài),那么為什么系統(tǒng)不對UI控件的訪問加上鎖機(jī)制呢?缺點(diǎn)有兩個(gè): ①首先加上鎖機(jī)制會(huì)讓UI訪問的邏輯變得復(fù)雜 ②鎖機(jī)制會(huì)降低UI訪問的效率,因?yàn)殒i機(jī)制會(huì)阻塞某些線程的執(zhí)行。 所以最簡單且高效的方法就是采用單線程模型來處理UI操作。

備注:此篇文章只作為筆記記錄。
感謝 文章原著:https://github.com/xiangjiana/Android-MS/blob/master/study/framework/Android%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.md

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容