91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WindowManager與Window在Android項目中有什么不同

發布時間:2020-11-21 16:12:29 來源:億速云 閱讀:213 作者:Leah 欄目:移動開發

這篇文章將為大家詳細講解有關WindowManager與Window在Android項目中有什么不同,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Window表示一個窗口的概念,Window是一個抽象類,它的具體實現是PhoneWindow。創建一個Window,需要通過WindowManager即可完成,WindowManager是外界訪問Window的入口,Window具體實現位于WindowManagerService中,WindowManager和WindowManagerService的交互是一個IPC的過程。Android中,所有的視圖都是通過Window來呈現,不管是Activity、Dialog、還是Toast,它們的視圖實際上都是附加在Window上,因此Window是實際View的直接管理者,單擊事件由Window傳遞給DecorView,然后再由DecorView傳遞給我們的View,就連Activity的設置視圖方法setContentView在底層也是通過Window來完成的。

Window和WindowManager

添加一個Window的過程,重點代碼是:

mWindowManager.addView(mFLoatingButton,mLayoutParams);

WindowManager.LayoutParams中有兩個flags和type參數。

Flags參數有三個Window屬性

  • FLAG_NOT_FOCUSABLE。表示Window不需要獲取焦點,也不需要接收各種輸入事件,最終事件會直接傳遞給下層的具有焦點的Window
  • FLAG_NOT_TOUCH_MODAL。在此模式下,系統會將當前Window區域以外的單擊事件傳遞給底層的Window,當前Window區域以內的單擊事件則自己處理,這個標記很重要,一般來說都需要開啟此標記,否則其他Window將無法收到單擊事件
  • FLAG_SHOW_WHEN_LOCKED。開啟此模式可以讓Window顯示在鎖屏的界面上。

Type參數表示Window的類型,有三種類型,分別是應用Window,子Window和系統Window,應用類Window對應一個Activity,子Window不能單獨存在,它需要附屬在特定的父Window之中,比如常見的Dialog就是一個子Window,系統Window是需要聲明權限在能創建的Window,比如Toast和系統狀態欄這些都是系統Window。

Window是分層的,每個Window都有對應的z-ordered,層級大的會覆蓋在層級小的Window的上面,在三類Window中,應用類的Window的層級范圍是1-99,子Window的層級范圍是1000-1999,系統Window的層級的范圍是2000-2999,這些層級范圍對應著WindowManager.LayoutParams的Type參數。如想要Window位于所有Window的最頂層,那么采用較大的層級即可。很顯然系統Window層級是最大的,而且系統層級有很多值。

WindowManager所提供的功能很簡單,常用有三個方法,即添加View,更新View和刪除View,這三個方法定義在ViewManager中,而WindowManager繼承了ViewManager。

Window的內部機制

Window是一個抽象的概念,每一個Window都對應著一個View和一個ViewRootImpl,Window和View通過ViewRootImpl來建立聯系,說明View才是Window存在的實體,在實際使用中無法直接訪問Window,對Window的訪問必須通過WindowManager。

Window的添加過程

Window的添加過程需要通過WindowManager的addView來實現,WindowManager是一個接口,它的真正實現是WindowManagerImpl類。

@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并沒有直接實現Window的三大操作,而是全部交給了WindowManagerGlobal來處理,WindowManagerGlobal以工廠的形式向外提供自己的實例。WindowManagerGlobal的addView方法主要分為如下幾步:

  • 檢查參數是否合法,如果是子Window那么還需要調整一些布局參數
  • 創建ViewRootImpl并將View添加到列表中
  • 通過ViewRootImpl來更新界面并完成Window的添加過程

Window的刪除過程

Window的刪除過程和添加過程一樣,都是先通過WindowManagerImpl后,在進一步通WindowManagerGlobal來實現的。里面用到一個dispatchDetachedFromWindow方法內部實現,這個方法主要做了四件事:

垃圾回收相關的工作,比如清除數據和消息、移除回調

通過Session的remove方法刪除Window

調用View的dispatchDetachedFromWindow方法,在內部會調用View的onDetachedFromWindow()以及onDetachedFromWindowInternal()

調用WindowManagerGlobal的doRemoveView方法刷新數據

Window的更新過程

主要是用到updateViewLayout方法,首先它需要更新View的LayoutParams并替換掉老的LayoutParams,接著再更新ViewRootImpl中的LayoutParams,這一步是通過ViewRootImpl的setLayoutParams方法來實現的。在ViewRootImpl中會通過scheduleTraversals方法對View進行重新布局,包括測量、布局、重繪這三個過程。

Window的創建過程

View是Android中的視圖呈現方式,但是View不能單獨存在,它必須附著在Window這個抽象的概念上面,因此有視圖的地方就有Window。

Activity的Window創建過程

如何創建,需要了解Activity啟動過程,比較復雜,但它最終由ActivityThred中的perfromLaunchActivity()來完成整個啟動過程,在這個方法內部會通過類加載器創建Activity的實例對象,并調用其attach方法為其關聯運行過程中所依賴的一系列上下文環境變量。

在Activity的attach方法里,系統會創建Activity所屬的Window對象并為其設置回調接口,Window對象的創建是通過PolicyManager的makeNewWindow方法實現的,對于Activity的setContentView的實現可以看出,Activity將具體實現交給了Window處理,而Window的具體實現是PhoneWindow,所以只需要看PhoneWindow相關邏輯即可,大致以下幾個步驟:

  • 如果沒有DecorView,那么就創建它。DecorView是一個FrameLayout,是Activity的頂級View,一般來說它的內部包含標題欄和內部欄。
  • 將View添加到DecorView的mContentParent中。
  • 回調Activity的onContentChanged方法通知Activity視圖已經發生改變。Activity的onContentChanged是一個空實現。

經過上面三個步驟,DecorView已經被創建初始化完畢,Activity的布局文件已經成功添加到了DecorView的mContentParent中,但是這個時候DecorView還沒有被WindowManager正式添加到Window中,真正被視圖調用是在Activity的onResume方法,接著會調用Activity的makeVisible(),正是在makeVisible方法中,DecorView真正地完成了添加和顯示這兩個過程。

Dialog的Window創建過程

Dialog的Window的創建過程和Activity類似,有以下幾個步驟:

  • 創建Window。同樣是通過PolicyManager的makeNewWindow方法來完成的。
  • 初始化DecorView并將Dialog的視圖添加到DecorView中。
  • 將DecorView添加到Window中并顯示。在Dialog的show方法中,會通過WindowManager將DecorView添加到Window中。

普通的Dialog有一個特殊之處,那就是必須采用Activity的Context,如果采用Application的Context,就會報錯。

Toast的Window創建過程

Toast和Dialog不同,它的工作過程稍微復雜。首先Toast也是基于Window來實現的,但是由于Toast具有定時取消這一功能,所以系統采用了Handler。在Toast的內部有兩類的IPC過程,第一類是Toast訪問NotificationManagerService,第二類是NotificationManagerService回調Toast的TN接口。

Toast屬于系統Window,它內部的視圖有兩種方式指定,一種是系統默認的樣式,另一種是通過setView方法來指定一個自定義View,不管如何,它們都對應Toast的一個View類型的內部成員mNextView。Toast提供了show和cancel分別用于顯示和隱藏Toast,它們的內部是一個IPC過程。

關于WindowManager與Window在Android項目中有什么不同就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

肥东县| 克山县| 巨野县| 扎兰屯市| 禹州市| 志丹县| 兴海县| 卓尼县| 安龙县| 舞阳县| 绥中县| 淳化县| 招远市| 海林市| 亚东县| 通化市| 福泉市| 靖江市| 黄龙县| 桐城市| 谢通门县| 吉林省| 苍溪县| 平安县| 双鸭山市| 永平县| 玛曲县| 温泉县| 苗栗县| 左贡县| 改则县| 资兴市| 普陀区| 喀喇沁旗| 池州市| 南京市| 常熟市| 辽宁省| 陕西省| 诏安县| 临漳县|