第8章 理解Window和WindowManager

概述

  1. Window是一個抽象類亲桥,具體實現(xiàn)是PhoneWindow。
  2. 創(chuàng)建一個Window,通過WindowManger就可以完成狭归。WindowMangager是外界訪問Window的入口
  3. Window的具體實現(xiàn)位于WindowMangerService(WMS)睛蛛,WindowManager和WMS的交互是一個IPC過程鹦马。
  4. Activity/Dialog/Toast,他們的視圖都是附加在Window上的忆肾。Window是View的直接管理者荸频。

8.1 Window和WindowManager

  1. 通過WindowManager添加Window的過程
mFloatingButton = new Button(this);
mFloatingButton.setText("test button");
mLayoutParams = new WindowManager.LayoutParams(
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,
        PixelFormat.TRANSPARENT);
mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
        | LayoutParams.FLAG_NOT_FOCUSABLE
        | LayoutParams.FLAG_SHOW_WHEN_LOCKED;
mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 100;
mLayoutParams.y = 300;
mFloatingButton.setOnTouchListener(this);
mWindowManager.addView(mFloatingButton, mLayoutParams);
  1. flags參數(shù)解析:

    1. FLAG_NOT_FOCUSABLE:表示window不需要獲取焦點,也不需要接收各種輸入事件客冈。
    2. FLAG_NOT_TOUCH_MODAL:系統(tǒng)會將window區(qū)域外的單擊事件傳遞給底層的window旭从,一般都需要開啟這個標記;
    3. FLAG_SHOW_WHEN_LOCKED:開啟此模式可以讓Window顯示在鎖屏的界面上场仲。
  2. type參數(shù)表示window的類型和悦,window共有三種類型:

    1. 應用window。應用window對應著一個Activity渠缕,層級范圍是1~99
    2. 子window鸽素。子window不能獨立存在,需要附屬在特定的父window之上亦鳞,比如Dialog就是子window付鹿。層級范圍是1000~1999.
    3. 系統(tǒng)window。系統(tǒng)window是需要聲明權(quán)限才能創(chuàng)建的window蚜迅,比如Toast和系統(tǒng)狀態(tài)欄這些都是系統(tǒng)window舵匾,需要聲明的權(quán)限是<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />。層級范圍是2000~2999
  3. WindowManager繼承自ViewManager谁不,常用的只有三個方法:

    1. addView
    2. updateViewLayout
    3. removeView

8.2 Window的內(nèi)部機制

  1. Window是一個抽象的概念坐梯,每個Window都對應一個View和ViewRootImpl,Window和View通過ViewRootImpl聯(lián)系刹帕,Window是以View的形式存在吵血。
  2. WindowManger是一個接口,真正實現(xiàn)是WindowManagerImpl類偷溺,WindowManagerImpl交給WindowMangerGlobal蹋辅。WindowMangerGlobal以工廠的形式提供自己的實例。
  3. 此處是橋接模式挫掏,WindowManagerImple將所有的操作全部委托給WindowManagerGlobal實現(xiàn)侦另。

8.2.1 Window的添加過程

  1. 檢查參數(shù)是否合法
  2. 創(chuàng)建ViewRootImpl將View添加到列表中
  3. 通過ViewRootImple更新界面并完成Window的添加過程。
    1. 在這里的setViez中會通過requesetLayout完成異步刷新請求。
    2. 會通過WindowSession對WMS進行Binder調(diào)用褒傅,由WMS實現(xiàn)Window的添加弃锐。WMS會對每個應用保留一個單獨的Session.

8.2.2 Window的刪除過程

  1. 通過findViewLocked查找待刪除的View的索引
  2. 調(diào)用removeViewLocked刪除
  3. 真正刪除View的邏輯在dispatchDetachedFromWindow
    1. 垃圾回收
    2. 通過Session的remove刪除Window,也是一個IPC過程
    3. onDetachedFromWindow(內(nèi)部資源回收殿托,比如停止線程霹菊、終止動畫)
    4. 刷新mViews、mRoots旋廷、mDyingViews等數(shù)據(jù)

8.2.3 Window的更新過程

  1. 更新View的LayoutParams
  2. 更新ViewRootImpl的LayoutParams
  3. 對View重新布局,包括measure礼搁、layout柳洋、draw三個過程

8.3 Window的創(chuàng)建過程

8.3.1 Activity的window創(chuàng)建過程

  1. Activity的啟動過程最終會由ActivityThread中的performLaunchActivity來完成整個啟動過程,在這個方法內(nèi)部會通過類加載器創(chuàng)建Activity的實例對象叹坦,并調(diào)用它的attach方法為其關(guān)聯(lián)運行過程中所依賴的一系列上下文環(huán)境變量熊镣;
  2. Activity實現(xiàn)了Window的Callback接口,當window接收到外界的狀態(tài)變化時就會回調(diào)Activity的方法募书,例如onAttachedToWindow绪囱、onDetachedFromWindow、dispatchTouchEvent等莹捡;
  3. Activity的Window是由PolicyManager來創(chuàng)建的鬼吵,它的真正實現(xiàn)是Policy類,它會新建一個PhoneWindow對象篮赢,Activity的setContentView的實現(xiàn)是由PhoneWindow來實現(xiàn)的齿椅;
  4. Activity的頂級View是DecorView,它本質(zhì)上是一個FrameLayout启泣。如果沒有DecorView涣脚,那么PhoneWindow會先創(chuàng)建一個DecorView,然后加載具體的布局文件并將view添加到DecorView的mContentParent中寥茫,最后就是回調(diào)Activity的onContentChanged通知Activity視圖已經(jīng)發(fā)生了變化遣蚀;
  5. 讓WindowManager能夠識別DecorView,在ActivityThread調(diào)用handleResumeActivity方法時纱耻,首先會調(diào)用Activity的onResume方法芭梯,然后會調(diào)用makeVisible方法,這個方法中DecorView真正地完成了添加和顯示過程弄喘。

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

  1. 創(chuàng)建Window 玖喘。通過PolicyManager的makeNewWindow完成
  2. setContentView,初始化DecorView蘑志,并將Dialog視圖放到DecorView中
  3. 將DecorView放到Window中顯示
  4. 當Dialog關(guān)閉累奈,通過WindowManger移除DecorView
  5. 普通Dialog必須才有Activity的Context贬派,應用Token只有Activity擁有。系統(tǒng)window不需要應用Token

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

  1. Toast屬于系統(tǒng)Window费尽,它內(nèi)部的視圖由兩種方式指定:一種是系統(tǒng)默認的演示;另一種是通過setView方法來指定一個自定義的View羊始。
  2. Toast的顯示和隱藏是IPC過程旱幼,都需要NotificationManagerService來實現(xiàn)。在Toast和NMS進行IPC過程時突委,NMS會跨進程回調(diào)Toast中的TN類中的方法柏卤,TN類是一個Binder類,運行在Binder線程池中匀油,所以需要通過Handler將其切換到當前發(fā)送Toast請求所在的線程缘缚,所以Toast無法在沒有Looper的線程中彈出。
  3. 對于非系統(tǒng)應用來說敌蚜,mToastQueue最多能同時存在50個ToastRecord桥滨,這樣做是為了防止DOS(Denial of Service,拒絕服務)弛车。因為如果某個應用彈出太多的Toast會導致其他應用沒有機會彈出Toast齐媒。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纷跛,隨后出現(xiàn)的幾起案子喻括,更是在濱河造成了極大的恐慌,老刑警劉巖贫奠,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唬血,死亡現(xiàn)場離奇詭異,居然都是意外死亡唤崭,警方通過查閱死者的電腦和手機拷恨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谢肾,“玉大人挑随,你說我怎么就攤上這事±盏” “怎么了兜挨?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長眯分。 經(jīng)常有香客問我拌汇,道長,這世上最難降的妖魔是什么弊决? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任噪舀,我火速辦了婚禮魁淳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘与倡。我一直安慰自己界逛,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布纺座。 她就那樣靜靜地躺著息拜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪净响。 梳的紋絲不亂的頭發(fā)上少欺,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音馋贤,去河邊找鬼赞别。 笑死,一個胖子當著我的面吹牛配乓,可吹牛的內(nèi)容都是我干的仿滔。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼犹芹,長吁一口氣:“原來是場噩夢啊……” “哼堤撵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起羽莺,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤实昨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盐固,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荒给,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年刁卜,在試婚紗的時候發(fā)現(xiàn)自己被綠了志电。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛔趴,死狀恐怖挑辆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情孝情,我是刑警寧澤鱼蝉,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站箫荡,受9級特大地震影響魁亦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜羔挡,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一洁奈、第九天 我趴在偏房一處隱蔽的房頂上張望间唉。 院中可真熱鬧,春花似錦利术、人聲如沸呈野。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽被冒。三九已至,卻和暖如春喉钢,著一層夾襖步出監(jiān)牢的瞬間姆打,已是汗流浹背良姆。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工肠虽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玛追。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓税课,卻偏偏與公主長得像,于是被迫代替她去往敵國和親痊剖。 傳聞我的和親對象是個殘疾皇子韩玩,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容