筆記:window與windowManager

window與windowManager


  • window在日常開發(fā)中如懸浮窗猴抹,它的實(shí)現(xiàn)是phoneWindow

  • window的創(chuàng)建通過(guò)WindowManager曼振,WindowManager是外界訪問(wèn)window的入口互艾。

windowManager獲壬缏丁:

      WindowManager      wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);

window通過(guò)setWindowManager()方法關(guān)聯(lián)WindowManager


  • window的具體實(shí)現(xiàn)位于WindowManagerService,WindowManager和WindowManagerService的交互是一個(gè)IPC過(guò)程

  • Android所有的視圖都是通過(guò)Window來(lái)呈現(xiàn)的胁后,不管是Activity店读,Dialog,還是Toast,它們的視圖實(shí)際上都是附加在Window上,因此攀芯,Window實(shí)際是View的實(shí)際管理者屯断,

  • Activity設(shè)置視圖的方法setContentView()底層也是通過(guò)Window來(lái)實(shí)現(xiàn)的

  • Window有3種類型
  1. 應(yīng)用類window 對(duì)應(yīng)一個(gè)Activity (1~99)
  2. 子window 不能單獨(dú)存在,需要依附在特定的父window之中侣诺,比如Dialog (1000~1999)
  3. 系統(tǒng)window 需要聲明權(quán)限才能創(chuàng)建的window殖演,比如toast,系統(tǒng)狀態(tài)欄 (2000~2999)

  • Window是分層的年鸳,每個(gè)Window都有對(duì)應(yīng)的z-ordered,層級(jí)大的會(huì)覆蓋在層級(jí)小的上面趴久,和html的z-index概念完全一致*

層級(jí)分別是上面的范圍,對(duì)應(yīng)著WindowManager.LayoutParams.type參數(shù)搔确,想要覆蓋在最上面彼棍,設(shè)置層級(jí)范圍最大即可灭忠,即系統(tǒng)層級(jí),一般選用:

TYPE_SYSTEM_OVERLAY

TYPE_SYSTEM_ERROR

mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR
同時(shí)聲明權(quán)限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

  • WindowManage僅提供了三個(gè)方法座硕,供開發(fā)者繼承使用:
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實(shí)現(xiàn)類是WindowManagerImpl

WindowManagerImpl并沒有直接實(shí)現(xiàn)Window的三大操作弛作,而是全部交給WindowManagerGlobal來(lái)處理,WindowManagerGlobal以工廠的形式向外提供實(shí)例-----典型的橋接模式


Activity Window創(chuàng)建流程

  • Activity的Window的創(chuàng)建在attach()方法里完成的华匾,在attach()方法里映琳,系統(tǒng)會(huì)創(chuàng)建Activity所屬的Window對(duì)象并為其設(shè)置回調(diào)接口,Window對(duì)象的創(chuàng)建是通過(guò)PolicyManager的makeNewWindow方法實(shí)現(xiàn)的

由于Activity實(shí)現(xiàn)了Window的CallBack接口蜘拉,因此Window接受到外界的回調(diào)就會(huì)回調(diào)到Activity中的方法萨西,如onAttachToWindow(),onDetachFromWindow(),dispatchTouchEvent()

PolicyManager 一個(gè)策略類,PolicyManager中實(shí)現(xiàn)的幾個(gè)工廠方法全部在策略接口IPolicy中聲明了诸尽,其中makeNewWindow()方法中完成new PhoneWindow()原杂。

(25版本中源碼Activity的attch方法中直接new PhoneWindow(),并沒有工廠模式)


  • Activity視圖怎么依附到Window上的

通過(guò)setContentView()來(lái)實(shí)現(xiàn)依附,setContent具體實(shí)現(xiàn):

  1. 如果沒有DecorView您机,就創(chuàng)建它
  2. 將View添加到DecorView的mContentParent中
  3. 回調(diào)Activity的onContentChanged()方法通知Activity的視圖已經(jīng)發(fā)生了改變

在ActivityThread中的handleResumeActivity方法中穿肄,首先會(huì)調(diào)用onResume方法,然后再調(diào)用Activity的makeVivible()方法,正是在makeVisible()方法中际看,DecorView真正完成了顯示和添加這兩個(gè)過(guò)程到這里Activity才被用戶看到咸产。

//Activity.java
    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

Dialog Window創(chuàng)建流程


  • Dialog使用的是PhoneWindow,同樣低版本使用了PlicyManager的makeNewWindow方法來(lái)完成,高版本直接new PhoneWindow();參考源碼

  • 創(chuàng)建步驟
  1. 創(chuàng)建Window
  2. 初始化DecorView仲闽,并將Dialog視圖添加到DecorView中

setContentView()

  1. 將DecorView添加到Window中并顯示
    在Dialog的show()方法中脑溢,通過(guò)WindowManager將DecorView添加到Window中,

     mWindowManager.addView(mDecor, l);
     mShowing = true;
    

  • 普通Dialog的Context必須使用Activity的Context赖欣,如果使用ApplicationContext,會(huì)報(bào)錯(cuò)屑彻。普通Dialog需要依附一個(gè)Window

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


  • Toast 內(nèi)部有兩類IPC通信過(guò)程
  1. Toast訪問(wèn)NotificationManagerService
  2. NotificationManagerService回調(diào)TN里的接口

  • TN是一個(gè)Binder類,用于NMS跨進(jìn)程調(diào)用TN的方法顶吮,如hide(),show()

所有TN里的hide,show()等方法都運(yùn)行在Binder線程池中社牲,所以需要Handle切換到當(dāng)前線程中去。

注意是切換到當(dāng)前線程中悴了。在沒有Looper的線程中搏恤,Toast無(wú)法正確運(yùn)行。


  • Toast的show()方法
    public void show() {
        if (mNextView == null) {
            throw new RuntimeException("setView must have been called");
        }

        INotificationManager service = getService();
        String pkg = mContext.getOpPackageName();
        TN tn = mTN;
        tn.mNextView = mNextView;

        try {
            service.enqueueToast(pkg, tn, mDuration);
        } catch (RemoteException e) {
            // Empty
        }
    }

enqueueToast首先將Toast封裝成ToastRecord對(duì)象湃交,并將其添加到mToastQueue隊(duì)列中熟空,mToastQueue其實(shí)是一個(gè)ArrayList,對(duì)于非系統(tǒng)應(yīng)用來(lái)說(shuō),該list長(zhǎng)度最多為50個(gè)ToastRecord,這么做是為了防止DOS(拒絕服務(wù)攻擊)搞莺,也就是如果大量循環(huán)彈toast那么其他應(yīng)用就無(wú)法彈了息罗。


  • Toast 原理也就是Binder通信,Toast調(diào)用Show方法才沧,內(nèi)部會(huì)將該toast與TN傳遞給運(yùn)行于系統(tǒng)進(jìn)程的NMS中阱当,由系統(tǒng)進(jìn)程控制TN的show方法俏扩,系統(tǒng)需要統(tǒng)一管理toast,NMS會(huì)將該toast放入一個(gè)ArrayList執(zhí)行隊(duì)列中弊添,while循環(huán)輪到該條toast時(shí)录淡,取出該toast對(duì)于的TN對(duì)象,再通過(guò)Binder通信油坝,執(zhí)行遠(yuǎn)程TN對(duì)象的show方法嫉戚,show方法會(huì)通過(guò)Handle讓show過(guò)程脫離Binder線程池,運(yùn)行于Looper線程中澈圈,show中實(shí)際通過(guò)WindowManage的addView方法彬檀,將View添加到window上。這樣就完成了一次Toast顯示過(guò)程瞬女,hide過(guò)程一樣窍帝。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诽偷,隨后出現(xiàn)的幾起案子坤学,更是在濱河造成了極大的恐慌,老刑警劉巖报慕,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件深浮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡眠冈,警方通過(guò)查閱死者的電腦和手機(jī)飞苇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蜗顽,“玉大人布卡,你說(shuō)我怎么就攤上這事」透牵” “怎么了忿等?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)刊懈。 經(jīng)常有香客問(wèn)我这弧,道長(zhǎng)娃闲,這世上最難降的妖魔是什么虚汛? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮皇帮,結(jié)果婚禮上卷哩,老公的妹妹穿的比我還像新娘。我一直安慰自己属拾,他們只是感情好将谊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布冷溶。 她就那樣靜靜地躺著,像睡著了一般尊浓。 火紅的嫁衣襯著肌膚如雪逞频。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天栋齿,我揣著相機(jī)與錄音苗胀,去河邊找鬼。 笑死瓦堵,一個(gè)胖子當(dāng)著我的面吹牛基协,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播菇用,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼澜驮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了惋鸥?” 一聲冷哼從身側(cè)響起杂穷,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揩慕,沒想到半個(gè)月后亭畜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迎卤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拴鸵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜗搔。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劲藐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出樟凄,到底是詐尸還是另有隱情聘芜,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布缝龄,位于F島的核電站汰现,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叔壤。R本人自食惡果不足惜瞎饲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炼绘。 院中可真熱鬧嗅战,春花似錦、人聲如沸俺亮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至东且,卻和暖如春启具,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背珊泳。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工富纸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旨椒。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓晓褪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親综慎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涣仿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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