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息息相關扭倾。盡情期待淀零。