1 饼记、WMS的職責(zé)
-
1.窗口管理
WMS是窗口的管理者,它負責(zé)窗口的啟動慰枕、添加和刪除具则,另外窗口的大小和層級也是由WMS進行管理的。窗口管理的核心成員有DisplayContent具帮、WindowToken和WindowState博肋。
-
2.窗口動畫
窗口間進行切換時,使用窗口動畫可以顯得更炫一些蜂厅,窗口動畫由WMS 的動畫子系統(tǒng)來負責(zé)匪凡,動畫子系統(tǒng)的管理者為WindowAnimator。
-
3.輸入系統(tǒng)的中轉(zhuǎn)站
通過對窗口的觸摸從而產(chǎn)生觸摸事件葛峻,InputManagerService(IMS)會對觸摸事件進行處理锹雏,它會尋找一個最合適的窗口來處理觸摸反饋信息,WMS是窗口的管理者术奖,它作為輸入系統(tǒng)的中轉(zhuǎn)站再合適不過了礁遵。
-
4.Surface管理
窗口并不具備繪制的功能,因此每個窗口都需要有一塊Surface來供自己繪制采记,為每個窗口分配Surface是由WMS來完成的佣耐。
WMS的職責(zé)可以簡單總結(jié)為如圖所示:
2、 WMS的創(chuàng)建過程
WMS是在SystemServer進程中創(chuàng)建的唧龄,查看SystemServer的main方法兼砖,如下所示:
在main方法中只調(diào)用了SystemServer的run方法,如下所示:
在注釋1處加載了動態(tài)庫libandroid_servers.so。
接下來在注釋2處創(chuàng)建SystemServiceManager讽挟,它會對系統(tǒng)的服務(wù)進行創(chuàng)建懒叛、啟動和生命周期管理。
在注釋3處的startBootstrapServices方法中用SystemServiceManager啟動了ActivityManagerService耽梅、PowerManagerService薛窥、PackageManagerService等服務(wù)。
在注釋4處的startCoreServices方法中則啟動了DropBoxManagerService眼姐、BatteryService诅迷、UsageStatsService和WebViewUpdateService。
在注釋5處的startOtherServices 方法中啟動了CameraService众旗、AlarmManagerService罢杉、VrManagerService等服務(wù)。
這些服務(wù)的父類均為SystemService贡歧。從注釋3滩租、注釋4、注釋5處的方法可以看出艘款,官方把系統(tǒng)服務(wù)分為了三種類型持际,分別是引導(dǎo)服務(wù)、核心服務(wù)和其他服務(wù)哗咆,其中其他服務(wù)是一些非緊要和不需要立即啟動的服務(wù)蜘欲,WMS就是其他服務(wù)的一種。我們來查看在startOtherServices方法中是如何啟動WMS的:
startOtherServices方法用于啟動其他服務(wù)晌柬,其他服務(wù)大概有100個左右姥份,上面的代碼只列出了WMS以及和它相關(guān)的IMS的啟動邏輯,剩余的其他服務(wù)的啟動邏輯也都大同小異年碘。
在注釋1澈歉、注釋2處分別得到Watchdog實例并對它進行初始化,Watchdog用來監(jiān)控系統(tǒng)的一些關(guān)鍵服務(wù)的運行狀況屿衅。
在注釋3處創(chuàng)建了IMS埃难,并賦值給IMS類型的inputManager對象。
在注釋4處執(zhí)行了WMS的main方法涤久,其內(nèi)部會創(chuàng)建WMS涡尘,需要注意的是main方法其中一個傳入的參數(shù)就是在注釋1處創(chuàng)建的IMS,WMS是輸入事件的中轉(zhuǎn)站响迂,其內(nèi)部包含了IMS引用并不意外考抄。
結(jié)合上文,我們可以得知WMS的main 方法是運行在SystemServer的run方法中的蔗彤,換句話說就是運行在“system_server”線程中川梅。
在注釋5和注釋6處分別將WMS和IMS注冊到ServiceManager中疯兼,這樣如果某個客戶端想要使用WMS,就需要先去ServiceManager中查詢信息贫途,然后根據(jù)信息與WMS 所在的進程建立通信通路吧彪,客戶端就可以使用WMS 了。
在注釋7處用來初始化屏幕顯示信息丢早,
在注釋8處則用來通知WMS来氧,系統(tǒng)的初始化工作已經(jīng)完成,其內(nèi)部調(diào)用了WindowManagerPolicy的systemReady方法香拉。
我們來查看注釋4處WMS的main方法,如下所示:
在注釋1處調(diào)用了DisplayThread的getHandler方法中狂,用來得到DisplayThread的Handler實例凫碌。
DisplayThread是一個單例的前臺線程,這個線程用來處理需要低延時顯示的相關(guān)操作胃榕,并只能由WindowManager盛险、DisplayManager和InputManager實時執(zhí)行快速操作。
在注釋1處的runWithScissors方法中使用了Java 8中的Lambda表達式勋又,它等價于如下代碼:
在注釋2處創(chuàng)建了WMS的實例苦掘,這個過程運行在Runnable的run方法中,而Runnable則傳到了DisplayThread對應(yīng)Handler的runWithScissors方法中楔壤,說明WMS的創(chuàng)建是運行在android.display線程中的鹤啡。需要注意的是,runWithScissors方法的第二個參數(shù)傳入的是0蹲嚣。
下面來查看Handler的runWithScissors方法做了什么:
開頭對傳入的Runnable和timeout進行了判斷递瑰,如果Runnable為null或者timeout小于0則拋出異常。
在注釋1處根據(jù)每個線程只有一個Looper 的原理來判斷當前的線程(system_server線程)是否是Handler所指向的線程(android.display線程)隙畜,如果是則直接執(zhí)行Runnable的run方法抖部,如果不是則調(diào)用BlockingRunnable的postAndWait方法,并將當前線程的Runnable作為參數(shù)傳進去议惰,
BlockingRunnable是Handler的內(nèi)部類慎颗,代碼如下所示:
在注釋2處將當前的BlockingRunnable 添加到Handler 的任務(wù)隊列中。
前面runWithScissors方法的第二個參數(shù)為0言询,因此timeout等于0俯萎,這樣如果mDone為false的話會一直調(diào)用注釋3處的wait方法使得當前線程(system_server線程)進入等待狀態(tài),那么等待的是哪個線程呢倍试?我們往上看讯屈,在注釋1處執(zhí)行了傳入的Runnable的run方法(運行在android.display線程),執(zhí)行完畢后在finally代碼塊中將mDone設(shè)置為true县习,并調(diào)用notifyAll方法喚醒處于等待狀態(tài)的線程涮母,這樣就不會繼續(xù)調(diào)用注釋3處的wait方法谆趾。因此得出結(jié)論,system_server線程等待的就是android.display線程叛本,一直到android.display線程執(zhí)行完畢再執(zhí)行system_server線程沪蓬,這是因為android.display線程內(nèi)部執(zhí)行了WMS的創(chuàng)建,而WMS的創(chuàng)建優(yōu)先級要更高来候。
最后查看WMS的構(gòu)造方法:
注釋1處用來保存?zhèn)鬟M來的IMS跷叉,這樣WMS就持有了IMS的引用。
在注釋2處通過DisplayManager的getDisplays方法得到Display數(shù)組(每個顯示設(shè)備都有一個Display實例)营搅,接著遍歷Display 數(shù)組云挟,
在注釋3處的createDisplayContentLocked 方法將Display 封裝成DisplayContent,DisplayContent用來描述一塊屏幕转质。
在注釋4處得到AMS實例园欣,并賦值給mActivityManager,這樣WMS就持有了AMS的引用休蟹。
在注釋5處創(chuàng)建了WindowAnimator沸枯,它用于管理所有的窗口動畫。
在注釋6處初始化了窗口管理策略的接口類WindowManagerPolicy(WMP)赂弓,它用來定義一個窗口策略所要遵循的通用規(guī)范绑榴。
在注釋7處將自身也就是WMS通過addMonitor方法添加到Watchdog中,Watchdog用來監(jiān)控系統(tǒng)的一些關(guān)鍵服務(wù)的運行狀況(比如傳入的WMS的運行狀況)盈魁,這些被監(jiān)控的服務(wù)都會實現(xiàn)Watchdog.Monitor接口翔怎。Watchdog每分鐘都會對被監(jiān)控的系統(tǒng)服務(wù)進行檢查,如果被監(jiān)控的系統(tǒng)服務(wù)出現(xiàn)了死鎖杨耙,則會殺死Watchdog所在的進程姓惑,也就是SystemServer進程。
查看注釋6處的initPolicy方法按脚,如下所示:
initPolicy方法和此前講的WMS的main方法的實現(xiàn)類似于毙,在注釋1處執(zhí)行了WMP的init方法,WMP是一個接口辅搬,init方法具體在PhoneWindowManager(PWM)中實現(xiàn)唯沮。
PWM的init方法運行在android.ui線程中,它的優(yōu)先級要高于initPolicy方法所在的android.display線程堪遂,因此android.display 線程要等PWM的init方法執(zhí)行完畢后介蛉,處于等待狀態(tài)的android.display線程才會被喚醒從而繼續(xù)執(zhí)行下面的代碼。
本文共提到了3個線程溶褪,分別是system_server币旧、android.display和android.ui,為了便于理解猿妈,下面給出這3個線程之間的關(guān)系吹菱,如圖所示巍虫。
三個線程之間的關(guān)系分為三個步驟來實現(xiàn):
(1)首先在system_server 線程中執(zhí)行了SystemServer的startOtherServices 方法,在startOtherServices方法中會調(diào)用WMS的main方法鳍刷,main方法會創(chuàng)建WMS占遥,創(chuàng)建的過程在android.display線程中實現(xiàn),創(chuàng)建WMS的優(yōu)先級更高输瓜,因此system_server線程要等WMS創(chuàng)建完成后瓦胎,處于等待狀態(tài)的system_server線程才會被喚醒從而繼續(xù)執(zhí)行下面的代碼。
(2)在WMS的構(gòu)造方法中會調(diào)用WMS的initPolicy方法尤揣,在initPolicy方法中又會調(diào)用PWM 的init 方法搔啊,PWM的init方法在android.ui線程中運行,它的優(yōu)先級要高于android.display線程北戏,因此“android.display”線程要等PWM的init方法執(zhí)行完畢后坯癣,處于等待狀態(tài)的android.display線程才會被喚醒從而繼續(xù)執(zhí)行下面的代碼。
(3)PWM的init方法執(zhí)行完畢后最欠,android.display線程就完成了WMS的創(chuàng)建,等待的system_server線程被喚醒后繼續(xù)執(zhí)行WMS的main 方法后的代碼邏輯惩猫,比如WMS的displayReady方法用來初始化屏幕顯示信息(SystemServer的startOtherServices方法的注釋7處)芝硬。
3.3 WMS的重要成員
-
1.mPolicy:WindowManagerPolicy
mPolicy是WindowManagerPolicy(WMP)類型的變量。WindowManagerPolicy是窗口管理策略的接口類轧房,用來定義一個窗口策略所要遵循的通用規(guī)范拌阴,并提供了WindowManager所有的特定的UI行為。它的具體實現(xiàn)類為PhoneWindowManager奶镶,這個實現(xiàn)類在WMS創(chuàng)建時被創(chuàng)建迟赃。WMP允許定制窗口層級和特殊窗口類型以及關(guān)鍵的調(diào)度和布局。
-
2.mSessions:ArraySet
mSessions是ArraySet類型的變量厂镇,元素類型為Session纤壁,它主要用于進程間通信,其他的應(yīng)用程序進程想要和WMS進程進行通信就需要經(jīng)過Session捺信,并且每個應(yīng)用程序進程都會對應(yīng)一個Session酌媒,WMS保存這些Session用來記錄所有向WMS提出窗口管理服務(wù)的客戶端。
-
3.mWindowMap:WindowHashMap
mWindowMap 是WindowHashMap類型的變量迄靠,WindowHashMap繼承了HashMap秒咨,它限制了HashMap的key值的類型為IBinder,value值的類型為WindowState掌挚。WindowState用于保存窗口的信息雨席,在WMS中它用來描述一個窗口。綜上得出結(jié)論吠式,mWindowMap就是用來保存WMS中各種窗口的集合陡厘。
-
4.mFinishedStarting:ArrayList
mFinishedStarting 是ArrayList 類型的變量抽米,元素類型為AppWindowToken,它是WindowToken的子類雏亚。要想理解mFinishedStarting的含義缨硝,需要先了解WindowToken是什么。WindowToken主要有兩個作用:
可以理解為窗口令牌罢低,當應(yīng)用程序想要向WMS 申請新創(chuàng)建一個窗口查辩,則需要向WMS出示有效的WindowToken。AppWindowToken作為WindowToken的子類网持,主要用來描述應(yīng)用程序的WindowToken 結(jié)構(gòu)宜岛,應(yīng)用程序中每個Activity 都對應(yīng)一個AppWindowToken。
WindowToken會將同一個組件(比如同一個Activity)的窗口(WindowState)集合在一起功舀,方便管理萍倡。
mFinishedStarting 就是用于存儲已經(jīng)完成啟動的應(yīng)用程序窗口(比如Activity)的AppWindowToken的列表。除了mFinishedStarting外辟汰,還有類似的mFinishedEarlyAnim和mWindowReplacementTimeouts列敲,其中mFinishedEarlyAnim存儲了已經(jīng)完成窗口繪制并且不需要展示任何已保存surface的應(yīng)用程序窗口的AppWindowToken。mWindowReplacementTimeout存儲了等待更換的應(yīng)用程序窗口的AppWindowToken帖汞,如果更換不及時戴而,舊窗口就需要被處理。
-
5.mResizingWindows:ArrayList
mResizingWindows是ArrayList類型的變量翩蘸,元素類型為WindowState所意。mResizingWindows是用來存儲正在調(diào)整大小的窗口的列表。與mResizingWindows 類似的還有mPendingRemove催首、mDestroySurface和mDestroyPreservedSurface等扶踊,其中mPendingRemove是在內(nèi)存耗盡時設(shè)置的,里面存有需要強制刪除的窗口郎任,mDestroySurface里面存有需要被銷毀的Surface秧耗,mDestroyPreservedSurface 里面存有窗口需要保存的等待銷毀的Surface,為什么窗口要保存這些Surface舶治?這是因為當窗口經(jīng)歷Surface變化時绣版,窗口需要一直保持舊Surface,直到新Surface的第一幀繪制完成歼疮。
-
6.mAnimator:WindowAnimator
mAnimator是WindowAnimator類型的變量杂抽,用于管理窗口的動畫以及特效動畫。
-
7.mH:H
mH 是H 類型的變量韩脏,系統(tǒng)的Handler 類缩麸,用于將任務(wù)加入到主線程的消息隊列中,這樣代碼邏輯就會在主線程中執(zhí)行赡矢。
8.mInputManager:InputManagerService
mInputManager 是InputManagerService 類型的變量杭朱,輸入系統(tǒng)的管理者阅仔。InputManagerService(IMS)會對觸摸事件進行處理,它會尋找一個最合適的窗口來處理觸摸反饋信息弧械,WMS是窗口的管理者八酒,因此WMS作為輸入系統(tǒng)的中轉(zhuǎn)站是再合適不過了。
3刃唐、 Window的添加過程(WMS處理部分)
我們知道Window的操作分為兩大部分羞迷,一部分是WindowManager處理部分,另一部分是WMS處理部分画饥。
無論是系統(tǒng)窗口還是Activity衔瓮,它們的Window的添加過程都會調(diào)用WMS的addWindow方法,由于這個方法代碼邏輯比較多抖甘,這里分為3個部分來閱讀热鞍。
3.1 addWindow方法part1
WMS的addWindow返回的是addWindow的各種狀態(tài),比如添加Window成功衔彻,無效的display等薇宠,這些狀態(tài)被定義在WindowManagerGlobal中。
在注釋1處根據(jù)Window的屬性艰额,調(diào)用WMP的checkAddPermission方法來檢查權(quán)限澄港,具體在PhoneWindowManager的checkAddPermission方法中實現(xiàn),如果沒有權(quán)限則不會執(zhí)行后續(xù)的代碼邏輯悴晰。
在注釋2處通過displayId 來獲得窗口要添加到哪個DisplayContent 上,如果沒有找到DisplayContent逐工,則返回WindowManagerGlobal.ADD_INVALID_DISPLAY 這一狀態(tài)铡溪,其中DisplayContent用來描述一塊屏幕。
在注釋3處泪喊,type代表一個窗口的類型棕硫,它的數(shù)值介于FIRST_SUB_WINDOW和LAST_SUB_WINDOW之間(1000~1999),這個數(shù)值定義在WindowManager中袒啼,說明這個窗口是一個子窗口哈扮。
在注釋4處,attrs.token是IBinder類型的對象蚓再,windowForClientLocked 方法內(nèi)部會根據(jù)attrs.token 作為key值從mWindowMap中得到該子窗口的父窗口滑肉。接著對父窗口進行判斷,如果父窗口為null或者type的取值范圍不正確則會返回錯誤的狀態(tài)摘仅。
3.2 addWindow方法part2
在注釋1處通過displayContent的getWindowToken方法得到WindowToken靶庙。
在注釋2處,如果有父窗口就將父窗口的type 值賦值給rootType娃属,如果沒有將當前窗口的type值賦值給rootType六荒。
接下來如果WindowToken為null护姆,則根據(jù)rootType或者type的值進行區(qū)分判斷,如果rootType值等于TYPE_INPUT_METHOD掏击、TYPE_WALLPAPER 等值時卵皂,則返回狀態(tài)值WindowManagerGlobal.ADD_BAD_APP_TOKEN,說明rootType值等于TYPE_INPUT_METHOD砚亭、TYPE_WALLPAPER 等值時是不允許WindowToken為null的灯变。
通過多次的條件判斷篩選,最后會在注釋3處隱式創(chuàng)建WindowToken钠惩,這說明當我們添加窗口時可以不向WMS提供WindowToken柒凉,前提是rootType和type的值不為前面條件判斷篩選的值。
WindowToken隱式和顯式的創(chuàng)建肯定是要加以區(qū)分的篓跛,注釋3處的第4個參數(shù)為false就代表這個WindowToken是隱式創(chuàng)建的膝捞。接下來的代碼邏輯就是WindowToken不為null的情況,根據(jù)rootType和type的值進行判斷愧沟,比如在注釋4處判斷如果窗口為應(yīng)用程序窗口蔬咬,在注釋5處將WindowToken 轉(zhuǎn)換為專門針對應(yīng)用程序窗口的AppWindowToken,然后根據(jù)AppWindowToken的值進行后續(xù)的判斷沐寺。
3.3 addWindow方法part3
在注釋1處創(chuàng)建了WindowState林艘,它存有窗口的所有的狀態(tài)信息,在WMS中它代表一個窗口混坞。在創(chuàng)建WindowState傳入的參數(shù)中狐援,this指的是WMS,client指的是IWindow究孕,IWindow會將WMS中窗口管理的操作回調(diào)給ViewRootImpl啥酱,token指的是WindowToken
緊接著在注釋2和注釋3處分別判斷請求添加窗口的客戶端是否已經(jīng)死亡、窗口的DisplayContent是否為null厨诸,如果是則不會再執(zhí)行下面的代碼邏輯镶殷。
在注釋4處調(diào)用了WMP的adjustWindowParamsLw方法,該方法在PhoneWindowManager中實現(xiàn)微酬,此方法會根據(jù)窗口的type對窗口的LayoutParams的一些成員變量進行修改绘趋。
在注釋5處調(diào)用WMP的prepareAddWindowLw方法,用于準備將窗口添加到系統(tǒng)中颗管。
在注釋6處將WindowState添加到mWindowMap中陷遮。
在注釋7處將WindowState添加到該WindowState對應(yīng)的WindowToken中(實際是保存在WindowToken的父類WindowContainer中),這樣WindowToken就包含了同一個組件的WindowState垦江。
3.4 addWindow方法總結(jié)
addWindow方法分了3個部分來進行講解拷呆,主要就是做了下面4件事:
對所要添加的窗口進行檢查,如果窗口不滿足一些條件,就不會再執(zhí)行下面的代碼邏輯茬斧。
WindowToken相關(guān)的處理腰懂,比如有的窗口類型需要提供WindowToken,沒有提供的話就不會執(zhí)行下面的代碼邏輯项秉,有的窗口類型則需要由WMS隱式創(chuàng)建WindowToken绣溜。
WindowState的創(chuàng)建和相關(guān)處理,將WindowToken和WindowState相關(guān)聯(lián)娄蔼。
創(chuàng)建和配置DisplayContent怖喻,完成窗口添加到系統(tǒng)前的準備工作。
3.5 Window的刪除過程
和Window的創(chuàng)建和更新過程一樣岁诉,要刪除Window需要先調(diào)用WindowManagerImpl的removeView方法锚沸,在removeView方法中又會調(diào)用WindowManagerGlobal的removeView方法,我們就從這里開始講起涕癣。為了表述得更易于理解哗蜈,本節(jié)將要刪除的Window(View)簡稱為V。WindowManagerGlobal的removeView方法如下所示:
在注釋1處找到V在View列表中的索引,
在注釋2處調(diào)用了removeViewLocked方法并將這個索引傳進去,如下所示:
在注釋1處根據(jù)傳入的索引在ViewRootImpl列表中獲得V的ViewRootImpl蜓氨。
在注釋2處得到InputMethodManager實例,如果InputMethodManager實例不為null則在注釋3處調(diào)用InputMethodManager的windowDismissed方法來結(jié)束V的輸入法相關(guān)的邏輯音比。
在注釋4處調(diào)用ViewRootImpl的die方法,如下所示:
在注釋1處如果immediate為ture(需要立即執(zhí)行)氢惋,并且mIsInTraversal值為false則執(zhí)行注釋2處的代碼洞翩,mIsInTraversal在執(zhí)行ViewRootImpl的performTraversals方法時會被設(shè)置為true,在performTraversals方法執(zhí)行完時被設(shè)置為false焰望,因此注釋1處可以理解為die 方法需要立即執(zhí)行并且此時ViewRootImpl 不再執(zhí)行performTraversals 方法骚亿。
在注釋2處的doDie方法如下所示:
在注釋1處用于檢查執(zhí)行doDie方法的線程的正確性,在注釋1處的內(nèi)部會判斷執(zhí)行doDie方法線程是否是創(chuàng)建V的原始線程柿估,如果不是就會拋出異常循未,這是因為只有創(chuàng)建V的原始線程才能夠操作V陷猫。
注釋2到注釋3處的代碼用于防止doDie方法被重復(fù)調(diào)用秫舌。
在注釋4處V有子View就會調(diào)用注釋5處的dispatchDetachedFromWindow方法來銷毀View。
在注釋6處如果V有子View并且不是第一次被添加绣檬,就會執(zhí)行后面的代碼邏輯足陨。
注釋7處的WindowManagerGlobal的doRemoveView方法,如下所示:
在WindowManagerGlobal中維護了和Window操作相關(guān)的三個列表娇未,doRemoveView方法會從這三個列表中清除V對應(yīng)的元素墨缘。
在注釋1處找到V對應(yīng)的ViewRootImpl在ViewRootImpl列表中的索引,接著根據(jù)這個索引從ViewRootImpl列表、布局參數(shù)列表和View列表中刪除與V對應(yīng)的元素镊讼。
我們接著回到ViewRootImpl的doDie方法宽涌,查看注釋5處的dispatchDetachedFromWindow方法做了什么:
在dispatchDetachedFromWindow方法中主要調(diào)用了IWindowSession的remove方法,IWindowSession在Server端的實現(xiàn)為Session蝶棋。
Session的remove方法如下所示:
接著查看WMS的removeWindow方法:
在注釋1處用于獲取Window對應(yīng)的WindowState卸亮,WindowState用于保存窗口的信息,在WMS中它用來描述一個窗口玩裙。
接著在注釋2處調(diào)用WindowState的removeIfPossible方法兼贸,如下所示:
又會調(diào)用removeIfPossible方法,如下所示:
removeIfPossible方法和它的名字一樣吃溅,并不是直接執(zhí)行刪除操作的溶诞,而是進行多個條件判斷過濾,滿足其中一個條件就會return决侈,推遲刪除操作螺垢。比如V正在運行一個動畫,這時就得推遲刪除操作颜及,直到動畫完成甩苛。通過這些條件判斷過濾就會執(zhí)行注釋1處的removeImmediately方法:
removeImmediately 方法如同它的名字一樣,用于立即進行刪除操作俏站。
在注釋1處的mRemoved為true意味著正在執(zhí)行刪除Window操作讯蒲,在注釋1到注釋2處之間的代碼用于防止重復(fù)刪除操作。
在注釋3處如果當前要刪除的Window是StatusBar或者NavigationBar就會將這個Window從對應(yīng)的控制器中刪除肄扎。
在注釋4處將V對應(yīng)的Session從WMS的ArraySet<Session> mSessions 中刪除并清除Session 對應(yīng)的SurfaceSession 資源(SurfaceSession是SurfaceFlinger的一個連接墨林,通過這個連接可以創(chuàng)建1個或者多個Surface并渲染到屏幕上)。
在注釋5處調(diào)用了WMS的postWindowRemoveCleanupLocked方法用于對V進行一些集中的清理工作犯祠。
Window 的刪除過程就講到這里旭等,雖然刪除的操作邏輯比較復(fù)雜,但是可以簡單地總結(jié)為以下4點:
檢查刪除線程的正確性衡载,如果不正確就拋出異常搔耕。
從ViewRootImpl列表、布局參數(shù)列表和View列表中刪除與V對應(yīng)的元素痰娱。
判斷是否可以直接執(zhí)行刪除操作弃榨,如果不能就推遲刪除操作。
執(zhí)行刪除操作梨睁,清理和釋放與V相關(guān)的一切資源鲸睛。
鏈接:https://juejin.cn/post/7120522752200540196
作者:復(fù)制粘貼改改改