WMS中performLayoutAndPlaceSurfacesLockedInner方法在api 24前后的實現(xiàn)

1.簡述

? ? ? ?在很多分析WindowManagerService的文章中都把它稱為Android GUI系統(tǒng)的“導演“,那既然身為導演自然就需要做”指導工作、分析劇本“的工作,這些工作反應在GUI中就是計算window的大小、執(zhí)行動畫、更新surface等。而這些關鍵工作在android api版本23以前(包括api 23)是由performLayoutAndPlaceSurfacesLockedInner這個方法實現(xiàn)的。

2.api ? 23以前的核心方法——performLayoutAndPlaceSurfacesLockedInner

? ? ? ?Android api 23以前在需要刷新系統(tǒng)UI的時候,例如切換Activity窗口,需要調用WMS的成員函數(shù)performLayoutAndPlaceSurfacesLocked來實現(xiàn):

? ? ? ? 該方法中具體的實現(xiàn)是一個do while循環(huán)中的performLayoutAndPlaceSurfacesLockedLoop 方法,這個循環(huán)的次數(shù)是6(暫不清楚這個6是如何而來)。

? ? ? ? ?在這個方法中終于見到了WMS中最為復雜的方法performLayoutAndPlaceSurfacesLockedInner,這個近600行的代碼中包含了計算窗口大小、執(zhí)行窗口動畫、刷新surface等工作。


? ? ? ? 關鍵的代碼在于這個try...catch中,里面對于窗口的變更進行計算,并且通過SurfaceControl對應到Surfacelinger中。 ?現(xiàn)在Android已經(jīng)逐漸開始支持多屏幕顯示,因此在這個方法里的先獲取到的DisplayContents的數(shù)量,然后在for循環(huán)中更新到每一個顯示屏幕中(目前基本上只有1)。關于layout的計算都在do...while這個循環(huán)中,循環(huán)跳出的條件是displayContent.pendingLayoutChanges != 0,也就是說當還有未處理的“l(fā)ayout changes”的時候會繼續(xù)執(zhí)行計算,而每輪循環(huán)末尾都會對這個displayContent.pendingLayoutChanges 進行賦值。當這個do...while結束之后進行的是對窗口需要執(zhí)行動畫的計算,而后執(zhí)行各個窗口的動畫。

? ? ? ? 之后的代碼都屬于收尾工作,包括銷毀不可見的窗口,刪除正在退出的WindowToken等。

? ? ? ?最后執(zhí)行的是scheduleAnimationLocked,里面是觸發(fā)動畫下一幀的邏輯,具體就是在下一個vsync信號來時觸發(fā)調用計算窗口透明度、尺寸、旋轉角度等值,然后將這些值設置到SurfaceFlinger中。

? ? ? ?這么一個洋洋灑灑600行代碼的方法,使得開發(fā)者閱讀起來相當困難,在維護上肯定也輕松不到哪里去,估計谷歌也考慮到了這點,因此在api 24之后估計對這個方法進行了改造,他們直接將WMS中的performLayoutAndPlaceSurfacesLockedInner方法去掉轉而新建了專門做計算的WindowSurfacePlacer類。

3.api 24之后的改動,WindowSurfacePlacer類分析

? ? ? ? WindowSurfacePlacer的出現(xiàn)原因可能是因為WMS的performLayoutAndPlaceSurfacesLockedInner方法過于臃腫影響可讀性(其實WindowSurfacePlacer里也沒好到哪兒去),更重要的原因為了實現(xiàn)7.0中的多窗口功能。

? ? ? ?在api 24的WMS中出現(xiàn)了一個方法——continueSurfaceLayout。這個方法作用簡單來說就是布局,跟進去后會發(fā)現(xiàn)它調用的是WindowSurfacePlacer的performSurfacePlacement,

? ? ? ? 繼而調用的是performSurfacePlacementLoop->performSurfacePlacementInner。是不是有點面熟?沒錯,原來WMS的窗口計算、通知繪制的邏輯被搬到了這兒。

? ? ? 與之前performLayoutAndPlaceSurfacesLockedInner不同的是,現(xiàn)在把do...while循環(huán)放到了更外層的方法中。至此WMS中最為復雜的方法分析告一段落,可見雖然方法比較復雜,但是條理還是非常清楚的。后續(xù)的文章我還會繼續(xù)分析Android 7.0(api 24)上多窗口的三種模式(多屏模式、畫中畫模式、Freeform模式)的具體實現(xiàn),當然與AMS,WMS息息相關。盡情期待。

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

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

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