Window和Window內(nèi)部機制
Window表示一個窗口的概念。Android所有的View都是是通過Window呈現(xiàn)的,比如Activity,Dialog,Toast等。如果有在桌面上創(chuàng)建一個懸浮窗的需求,就需要用到Window.Window也是View的直接管理者。
Window是一個抽象類,PhoneWindow是其具體實現(xiàn)。Windwo創(chuàng)建通過WindowManager,而具體實現(xiàn)是在WindowManagerService中,這兩者交互是個IPC過程。
WindowManager常用的功能:
addView(),updateViewLayout(),removeView();
Window內(nèi)部機制
Window是一個抽象的概念,每一個Window都對應著一個View和ViewRootImpl。Window和View通過ViewRootImpl建立聯(lián)系。所以Window不是單獨存在的,他是以View的形式存在。
Window的添加過程
Window添加過程,通過WindowManager的addView,而WindowManager是一個接口,真正實現(xiàn)它的是WindowManagerImpl。在WindowManagerImpl的三大操作中(增,更,查),全部委托給WindowManagerGlobal來實現(xiàn)。
在WindowManagerGlobal中創(chuàng)建ViewRootImpl并將View添加到列表中。
通過ViewRootImpl來更細頁面,在通過WindowSession(IWindowSession),它是一個Binder對象。這就是一次IPC調(diào)用。在Session內(nèi)部通過WindowManagerService來實現(xiàn)Window的添加。
Window的刪除過程
通過WindowMImpl,在通過WindowMGlobal中的removeView實現(xiàn),在這remove是通過ViewRootImpl來完成刪除操作的。
Window的更新過程
通過WindowMImpl,在通過WindowMGlobal中的updateViewLatyout實現(xiàn),在通過更新ViewRootImpl中的LayoutParams,通過setLayoutParams方法來實現(xiàn)。這個過程最終是由WindowManagerService的relayoutWindow()來具體實現(xiàn),也是一個IPC過程。
Window的創(chuàng)建過程
Activity的Window創(chuàng)建過程
在Activity的attach方法房中,系統(tǒng)會創(chuàng)建Activity所屬的Window對象并為其設置回調(diào)接口。Window對象是通過PolicyManager的makeNewWindow方法實現(xiàn)的。PolicyManager真正實現(xiàn)的是Policy類。
Policy類中的makeNewWindow方法中可知Window的具體實現(xiàn)是PhoneWindow。setContentView實際是由PhoneWindow的setContentView來實現(xiàn)
PhoneWindow中setContentView的步驟:
1.沒有DecorView就創(chuàng)建一個。
2.將View添加到DecorView的mContentParene中
3.回調(diào)Activity的onContentChanged方法通知Activity視圖已經(jīng)發(fā)生改變
Dialog的Window創(chuàng)建過程
1.創(chuàng)建Window和Activity的Window創(chuàng)建過程類似,也是通過PolicyManager的makeNewWindow方法實現(xiàn)的。
2.初始化DecorView將Dialog的視圖添加到DecorView中
3.通過WindowManager將DecorView添加到Window中并顯示,
Toast的Window創(chuàng)建過程
Toast的顯示和隱藏都是通過NotificationManagerService來實現(xiàn),NMS運行在系統(tǒng)進程中。Toast和NMS進行IPC過程時,當NMS處理Toast的顯示或者隱藏會跨進程回調(diào)TN(一個Binder類)中的方法。
Toast的顯示過程:首先調(diào)用NMS中enqueueToast,enqueueToast首先將Toast請求封裝為ToastRecord對象并添加到mToastQueue隊列中,然后NMS就會通過showNextToastLocked方法來顯示當前的Toast,Toast顯示是由ToastRecord的callback來完成的。這個callback實際就是Toast中的TN對象的遠程Binder。
Toast的隱藏過程也是通過ToastRecord的callback完成,同樣也是一個IPC過程。
在TN的handleShow中會將Toast的視圖添加到Window中,在handleHide中會將Toast視圖從Window中移除。
一個應用中的Activity的個數(shù):
Window有三種類型:應用Window、子Window和系統(tǒng)Window。應用Window對應著一個Activity,子Window不能單獨存在,需要附屬在特定的Window中,比如Dialog。系統(tǒng)Window需要聲明權限才能創(chuàng)建Window,比如Toast和系統(tǒng)狀態(tài)欄。
所以應用中Window的個數(shù)是:Activity數(shù)量+Dialog數(shù)量+使用的Toast數(shù)量+懸浮窗個數(shù)。