第8章 理解Window和WindowManager

(1)Window是抽象類苛吱,具體實現(xiàn)是PhoneWindow酪术,通過WindowManager就可以創(chuàng)建Window。WindowManager是外界訪問Window的入口翠储,但是Window的具體實現(xiàn)是在WindowManagerService中绘雁,WindowManager和WindowManagerService的交互是一個IPC過程橡疼。所有的視圖例如Activity、Dialog咧七、Toast都是附加在Window上的衰齐。

(2)通過WindowManager添加View的過程:將一個Button添加到屏幕坐標(biāo)為(100,300)的位置上

mFloatingButton = new Button(this);
mFloatingButton.setText("test button");
mLayoutParams = new WindowManager.LayoutParams(
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,
        PixelFormat.TRANSPARENT);//0,0 分別是type和flags參數(shù),在后面分別配置了
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);

flags參數(shù)解析:

FLAG_NOT_FOCUSABLE:表示window不需要獲取焦點继阻,也不需要接收各種輸入事件耻涛。此標(biāo)記會同時啟用FLAG_NOT_TOUCH_MODAL,最終事件會直接傳遞給下層的具有焦點的window瘟檩;

FLAG_NOT_TOUCH_MODAL:在此模式下抹缕,系統(tǒng)會將window區(qū)域外的單擊事件傳遞給底層的window,當(dāng)前window區(qū)域內(nèi)的單擊事件則自己處理墨辛,一般都需要開啟這個標(biāo)記卓研;

FLAG_SHOW_WHEN_LOCKED:開啟此模式可以讓W(xué)indow顯示在鎖屏的界面上。 [奇怪的是我刪除這個標(biāo)記還是在鎖屏看到了添加的組件orz]

type參數(shù)表示window的類型睹簇,window共有三種類型:應(yīng)用window奏赘,子window和系統(tǒng)window。應(yīng)用window對應(yīng)著一個Activity太惠,子window不能獨立存在磨淌,需要附屬在特定的父window之上,比如Dialog就是子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" />埃脏。

(3)window是分層的搪锣,每個window都對應(yīng)著z-ordered,層級大的會覆蓋在層級小的上面彩掐,應(yīng)用window的層級范圍是1~99构舟,子window的層級范圍是1000~1999,系統(tǒng)window的層級范圍是2000~2999堵幽。

[注意旁壮,應(yīng)用window的層級范圍并不是1~999喲]

(4)WindowManager繼承自ViewManager,常用的只有三個方法:addView谐檀、updateViewremoveView抡谐。

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

(1)Window是一個抽象的概念,不是實際存在的桐猬,它也是以View的形式存在麦撵。在實際使用中無法直接訪問Window,只能通過WindowManager才能訪問Window。每個Window都對應(yīng)著一個View和一個ViewRootImpl免胃,Window和View通過ViewRootImpl來建立聯(lián)系音五。

(2)Window的添加、刪除和更新過程都是IPC過程羔沙,以Window的添加為例躺涝,WindowManager的實現(xiàn)類對于addViewupdateViewremoveView方法都是委托給WindowManagerGlobal類扼雏,該類保存了很多數(shù)據(jù)列表坚嗜,例如所有window對應(yīng)的view集合mViews、所有window對應(yīng)的ViewRootImpl的集合mRoots等诗充,之后添加操作交給了ViewRootImpl來處理苍蔬,接著會通過WindowSession來完成Window的添加過程,這個過程是一個IPC調(diào)用蝴蜓,因為最終是通過WindowManagerService來完成window的添加的碟绑。

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

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

1.Activity的啟動過程很復(fù)雜,最終會由ActivityThread中的performLaunchActivity來完成整個啟動過程茎匠,在這個方法內(nèi)部會通過類加載器創(chuàng)建Activity的實例對象格仲,并調(diào)用它的attach方法為其關(guān)聯(lián)運行過程中所依賴的一系列上下文環(huán)境變量;

2.Activity實現(xiàn)了Window的Callback接口诵冒,當(dāng)window接收到外界的狀態(tài)變化時就會回調(diào)Activity的方法凯肋,例如onAttachedToWindowonDetachedFromWindow造烁、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.還有一個步驟是讓W(xué)indowManager能夠識別DecorView我碟,在ActivityThread調(diào)用handleResumeActivity方法時,首先會調(diào)用Activity的onResume方法姚建,然后會調(diào)用makeVisible方法矫俺,這個方法中DecorView真正地完成了添加和顯示過程。

ViewManager vm = getWindowManager();
vm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;

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

1.過程與Activity的Window創(chuàng)建過程類似,普通的Dialog的有一個特別之處厘托,即它必須采用Activity的Context友雳,如果采用Application的Context會報錯。原因是Application沒有應(yīng)用token铅匹,應(yīng)用token一般是Activity擁有的押赊。[service貌似也有token?]

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

1.Toast屬于系統(tǒng)Window,它內(nèi)部的視圖由兩種方式指定:一種是系統(tǒng)默認(rèn)的演示包斑;另一種是通過setView方法來指定一個自定義的View流礁。

2.Toast具有定時取消功能,所以系統(tǒng)采用了Handler舰始。Toast的顯示和隱藏是IPC過程崇棠,都需要NotificationManagerService來實現(xiàn)。在Toast和NMS進(jìn)行IPC過程時丸卷,NMS會跨進(jìn)程回調(diào)Toast中的TN類中的方法枕稀,TN類是一個Binder類,運行在Binder線程池中谜嫉,所以需要通過Handler將其切換到當(dāng)前發(fā)送Toast請求所在的線程萎坷,所以Toast無法在沒有Looper的線程中彈出。

3.對于非系統(tǒng)應(yīng)用來說沐兰,mToastQueue最多能同時存在50ToastRecord哆档,這樣做是為了防止DOS(Denial of Service,拒絕服務(wù))住闯。因為如果某個應(yīng)用彈出太多的Toast會導(dǎo)致其他應(yīng)用沒有機(jī)會彈出Toast瓜浸。

其他學(xué)習(xí)資料

1.Android應(yīng)用開發(fā)之(WindowManager類使用)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市比原,隨后出現(xiàn)的幾起案子插佛,更是在濱河造成了極大的恐慌,老刑警劉巖量窘,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雇寇,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚌铜,警方通過查閱死者的電腦和手機(jī)锨侯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冬殃,“玉大人囚痴,你說我怎么就攤上這事∩笤幔” “怎么了深滚?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵骂束,是天一觀的道長。 經(jīng)常有香客問我成箫,道長展箱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任蹬昌,我火速辦了婚禮混驰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘皂贩。我一直安慰自己栖榨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布明刷。 她就那樣靜靜地躺著婴栽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辈末。 梳的紋絲不亂的頭發(fā)上愚争,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音挤聘,去河邊找鬼轰枝。 笑死,一個胖子當(dāng)著我的面吹牛组去,可吹牛的內(nèi)容都是我干的鞍陨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼从隆,長吁一口氣:“原來是場噩夢啊……” “哼诚撵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起键闺,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤寿烟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后艾杏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韧衣,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡盅藻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年购桑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氏淑。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡勃蜘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出假残,到底是詐尸還是另有隱情缭贡,我是刑警寧澤炉擅,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站阳惹,受9級特大地震影響谍失,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜莹汤,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一快鱼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纲岭,春花似錦抹竹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至喇闸,卻和暖如春袄琳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背燃乍。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工跨蟹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人橘沥。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓窗轩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親座咆。 傳聞我的和親對象是個殘疾皇子痢艺,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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