要點提煉|開發(fā)藝術(shù)之Window

多數(shù)情況我們是和ActivityView打交道洗鸵,在之前學(xué)習(xí)中也都接觸過,本篇來深入學(xué)習(xí)和它們有緊密聯(lián)系的Window椿息,主要內(nèi)容:

  • Window&WindowManager
  • Window的內(nèi)部機制(添加涛菠、刪除铺然、更新)
  • Window的創(chuàng)建過程(Activity、Dialog且轨、Toast)

1.Window&WindowManager

a.Window&PhoneWindow:
Window是一個抽象類糕殉,它定義了頂級窗體樣式和行為。其唯一的實現(xiàn)類是PhoneWindow殖告。

推薦閱讀Window阿蝶,PhoneWindow,DecorView黄绩,setContentView源碼理解

b.Window&View:
每個Window都對應(yīng)一個View和一個ViewRootImpl羡洁,Window和View通過ViewRootImpl來建立聯(lián)系。Window并不可見爽丹,它實際以View的形式存在筑煮,它是View的直接管理者

c.Window&WindowManager:
實際使用中無法訪問Window粤蝎,對Window的訪問必須通過WindowManager真仲,對Window的操作通過它完成。

  • 例如:通過WindowManager添加Window
//將一個Button添加到屏幕為(100,300)的位置
mFloatingButton = new Button(this);
mFloatingButton.setText("test button");

mLayoutParams = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,PixelFormat.TRANSPARENT);//第三個參數(shù)代表flags初澎,第四個參數(shù)代表type

mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
        | LayoutParams.FLAG_NOT_FOCUSABLE
        | LayoutParams.FLAG_SHOW_WHEN_LOCKED;//配置flags
mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;//配置type
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;//配置gravity
mLayoutParams.x = 100;//相對于gravity
mLayoutParams.y = 300;//相對于gravity

mFloatingButton.setOnTouchListener(this);
mWindowManager.addView(mFloatingButton, mLayoutParams);

這里依次介紹WindowManager的三個重要參數(shù):

  • flags:表示W(wǎng)indow的屬性秸应。主要的可選值含義:
    • FLAG_NOT_FOCUSABLE:表示W(wǎng)indow不需要獲取焦點,也不需要接收各種輸入事件碑宴,此標(biāo)記會同時啟動FLAG_NOT_TOUCH_MODEL软啼,最終事件會傳遞給下層的具有焦點的Window。
    • FLAG_NOT_TOUCH_MODAL:表示系統(tǒng)會將當(dāng)前Window區(qū)域以外的單擊事件傳遞給底層的Window延柠,而區(qū)域以內(nèi)的單擊事件則自己處理祸挪。一般都需要開啟此標(biāo)記,否則其他Window將無法收到單擊事件贞间。
    • FLAG_SHOW_WHEN_LOCKED:表示W(wǎng)indow可顯示在鎖屏界面贿条。
  • type:表示W(wǎng)indow的類型。Window有三種類型:
    • 應(yīng)用Window:對應(yīng)一個Activity增热。
    • 子Window:不能單獨存在整以,需附屬特定的父Window。如Dialog钓葫。
    • 系統(tǒng)Window: 需申明權(quán)限才能創(chuàng)建悄蕾。如Toast。
  • Window是分層的,見下表帆调。
  • 層級大的會覆蓋在層級小的Window上面奠骄。
  • 對應(yīng)WindowManager.LayoutParams的type參數(shù)。
  • gravity:表示W(wǎng)indow的位置番刊。
    • 默認是屏幕中間含鳞。
    • xy值相對于gravity芹务。

d.WindowManager&WindowManagerService:
Window的具體實現(xiàn)位于WindowManagerService中蝉绷。WindowManager和WindowManagerService的交互是一個IPC(跨進程通信)過程。


2.Window的內(nèi)部機制

  • WindowManager對Window主要有三大操作:添加枣抱、更新和刪除熔吗。這三個方法主要是定義在ViewManager接口中:
public interface ViewManager
{
    public void addView(View view, ViewGroup.LayoutParams params);//添加過程
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);//更新過程
    public void removeView(View view);//刪除過程
}
  • WindowManager也是一個接口,它繼承了ViewManager接口:
public interface WindowManager extends ViewManager {}
  • WindowManager的具體實現(xiàn)類是WindowManagerImpl
public final class WindowManagerImpl implements WindowManager{
        @Override
        public void addView(View view, ViewGroup.LayoutParams params){
            mGlobal.addView(view, params, mDisplay, mParentWindow);
        }
        
        @Override
        public void updateViewLayout(View view, ViewGroup.LayoutParams params){
            mGlobal.updateViewLayout(view, params);
        }
        
        @Override
        public void removeView(View view){
            mGlobal.removeView(view, false);
        }
}
  • 由以上代碼可見佳晶,WindowManagerImpl并沒有直接實現(xiàn)Window的三大操作桅狠,而是交給了WindowManagerGlobal。WindowManagerGlobal以單例模式向外提供自己的實例:
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

一幅圖說明這幾個類的關(guān)系:

因此轿秧,通過WindowManagerGlobal的addView()中跌、updateViewLayout()、removeView()實現(xiàn)WindowManager對Window的添加菇篡、刪除和修改漩符。

下面分別來看WindowManagerGlobal對Window操作的大致過程:

a.Window的添加過程:

b.Window的刪除過程

c.Window的更新過程

不難發(fā)現(xiàn), 以上驗證了之前的總結(jié):

  • Windows的三大操作最終都會通過一個IPC過程移交給WindowManagerService驱还。
  • Window和View通過ViewRootImpl來聯(lián)系嗜暴,ViewRootImpl可控制View的測量、布局和重繪铝侵。

推薦閱讀:源碼剖析之------Window的內(nèi)部實現(xiàn)機制灼伤、我眼中的Window創(chuàng)建/添加/刪除/更新過程


3.Window的創(chuàng)建過程

由于View必須依附Window才能呈現(xiàn)出來,因此有View的地方必有Window咪鲜。在Android中可以提供View的地方有Activity、Dialog和Toast撞鹉,下面分別來看以上三種Window的大致創(chuàng)建過程:

a.Activity的Window創(chuàng)建過程

推薦閱讀Activity的Window創(chuàng)建過程分析(源碼)

b.Dialog的Window創(chuàng)建過程

Step1:創(chuàng)建WindowDialog疟丙。和Activity類似,同樣是通過PolicyManager.makeNewWindow()來實現(xiàn)鸟雏。

Step2:初始化DecorView并將Dialog的視圖添加到DecorView中去享郊。和Activity類似,同樣是通過Window.setContentView()來實現(xiàn)孝鹊。

Step3:將DecorView添加到Window中顯示炊琉。和Activity一樣,都是在自身要出現(xiàn)在前臺時才會將添加Window。

  • Dialog.show()方法:完成DecorView的顯示苔咪。
  • WindowManager.remoteViewImmediate()方法:當(dāng)Dialog被dismiss時移除DecorView锰悼。

c.Toast的Window創(chuàng)建過程

①Toast的內(nèi)部的視圖由兩種方式指定:

  • 系統(tǒng)默認的樣式;
  • 通過setView()指定一個自定義View团赏。

這里見技能篇之Toast的使用

②Toast具有定時取消功能箕般,故系統(tǒng)采用Handler做定時處理。

③在Toast內(nèi)部有兩類IPC過程:

  • Toast訪問NotificationManagerService(NMS)舔清;
  • NotificationManagerService回調(diào)Toast里的TN接口丝里。

④Toast提供方法show()cancel()分別用于顯示和隱藏Toast。

  • Toast的顯示和隱藏都需要通過NMS來實現(xiàn)体谒,由于NMS運行在系統(tǒng)進程中杯聚,故需通過遠程調(diào)用的方式來進行顯示和隱藏Toast。
  • NMS處理Toast的顯示和隱藏請求時會跨進程回調(diào)TN中的方法抒痒,由于TN運行在Binder線程池中幌绍,故需通過Handler將其切換到當(dāng)前線程(發(fā)送Toast請求的線程)。

NMS只是起到了管理Toast隊列及其延時的效果评汰,Toast 的顯示和隱藏實際是通過TN來實現(xiàn)的纷捞。

推薦閱讀:Android對話框Dialog,PopupWindow被去,Toast的實現(xiàn)機制


希望這篇文章對你有幫助~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末主儡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子惨缆,更是在濱河造成了極大的恐慌糜值,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坯墨,死亡現(xiàn)場離奇詭異寂汇,居然都是意外死亡,警方通過查閱死者的電腦和手機捣染,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門骄瓣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耍攘,你說我怎么就攤上這事榕栏。” “怎么了蕾各?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵扒磁,是天一觀的道長。 經(jīng)常有香客問我式曲,道長妨托,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮兰伤,結(jié)果婚禮上内颗,老公的妹妹穿的比我還像新娘。我一直安慰自己医清,他們只是感情好起暮,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著会烙,像睡著了一般负懦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柏腻,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天纸厉,我揣著相機與錄音,去河邊找鬼五嫂。 笑死颗品,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沃缘。 我是一名探鬼主播躯枢,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼槐臀!你這毒婦竟也來了锄蹂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤水慨,失蹤者是張志新(化名)和其女友劉穎得糜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晰洒,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡朝抖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谍珊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片治宣。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砌滞,靈堂內(nèi)的尸體忽然破棺而出炼七,到底是詐尸還是另有隱情,我是刑警寧澤布持,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站陕悬,受9級特大地震影響题暖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一胧卤、第九天 我趴在偏房一處隱蔽的房頂上張望唯绍。 院中可真熱鬧,春花似錦枝誊、人聲如沸况芒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绝骚。三九已至,卻和暖如春祠够,著一層夾襖步出監(jiān)牢的瞬間压汪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工古瓤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留止剖,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓落君,卻偏偏與公主長得像穿香,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绎速,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353