Android GUI之Window、WindowManager,windowmanager
通過前幾篇的文章(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#gui ),我們清楚了Activity實際上是將視圖的建立和顯示交給了Window對象進行了處理並分析了視圖的測量、布局及繪製過程。本篇文章將繼續詳細分析Window及WindowManger的作用。
首先,我們將通過弄清楚他們之間的關係。
通過前幾篇的文章,我們清楚了Activity實際上是將視圖的建立和顯示交給了Window對象進行了處理並分析了視圖的測量、布局及繪製過程。本篇文章將繼續詳細分析Window及WindowManger的作用。
首先,我們將通過弄清楚他們之間的關係。
/** Flag for the "options panel" feature. This is enabled by default. */ public static final int FEATURE_OPTIONS_PANEL = 0; /** Flag for the "no title" feature, turning off the title at the top * of the screen. */ public static final int FEATURE_NO_TITLE = 1; //無標題列 /** Flag for the progress indicator feature */ public static final int FEATURE_PROGRESS = 2; //在標題列上添加載入進度條 /** Flag for having an icon on the left side of the title bar */ public static final int FEATURE_LEFT_ICON = 3; /** Flag for having an icon on the right side of the title bar */ public static final int FEATURE_RIGHT_ICON = 4; /** Flag for indeterminate progress */ public static final int FEATURE_INDETERMINATE_PROGRESS = 5; /** Flag for the context menu. This is enabled by default. */ public static final int FEATURE_CONTEXT_MENU = 6; /** Flag for custom title. You cannot combine this feature with other title features. */public static final int FEATURE_CUSTOM_TITLE = 7;public static final int FEATURE_ACTION_BAR = 8;public static final int FEATURE_ACTION_BAR_OVERLAY = 9;public static final int FEATURE_ACTION_MODE_OVERLAY = 10;public static final int FEATURE_MAX = FEATURE_ACTION_MODE_OVERLAY; /** Flag for setting the progress bar's visibility to VISIBLE */ public static final int PROGRESS_VISIBILITY_ON = -1; /** Flag for setting the progress bar's visibility to GONE */ public static final int PROGRESS_VISIBILITY_OFF = -2; /** Flag for setting the progress bar's indeterminate mode on */ public static final int PROGRESS_INDETERMINATE_ON = -3; /** Flag for setting the progress bar's indeterminate mode off */ public static final int PROGRESS_INDETERMINATE_OFF = -4; /** Starting value for the (primary) progress */ public static final int PROGRESS_START = 0; /** Ending value for the (primary) progress */ public static final int PROGRESS_END = 10000; /** Lowest possible value for the secondary progress */ public static final int PROGRESS_SECONDARY_START = 20000; /** Highest possible value for the secondary progress */public static final int PROGRESS_SECONDARY_END = 30000;
那麼如何應用這些視窗特徵呢?在Activity中,我們可以調用方法requestWindowFeature,實際此方法是調用了Window中的requestFeature的方法,方法原型如下:
public boolean requestFeature(int featureId) { final int flag = 1<<featureId; mFeatures |= flag; mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag; return (mFeatures&flag) != 0;}
注意此方法必須在setContentView方法之前調用才有效,一旦應用了這些視窗特徵後續不可更改。
在window中定義了一個CallBack介面,此介面中一定了一系列的時間回調方法,用於處理UI的各種事件,如按鍵事件、觸摸事件、軌跡球、Accessibility事件、菜單事件等等。比如Activity就實現了此介面。關於事件這塊的內容,我們後面專門做分析研究。
在window中還定義了WindowManager,從字面上可以理解為視窗管理器,實際上它並不是真正的視窗管理器,WindowManager Service才是Android中真正意義上的視窗管理器。實際上Window內的WindowManager只是用於管理Window內部的視圖,通過方法setWindowManager,可以看到Window中是如何建立WindowManager的,具體源碼如下:
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); }
通過該方法我們可以看到通過WindowManagerImpl的createLoaclWindowManager方法建立了一個WindowManager對象。
從中,我們看出WindowManager介面是繼承了ViewManager介面,從源碼中可以看出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);}
很好理解主要用於window中view的添加、更新和刪除。
WindowManager介面內容也比較簡單,除了繼承自ViewManager中的方法外,還定義了3個內部類和兩個方法,具體API如下。
在這裡我們要重點關注一下LayoutParams這個內部類,此類定義了許多與視窗相關的屬性,比如位置、視窗類別型(主要有三類:Application Windows、Sub-windows、System windows)、行為選項標誌、視窗透明度等等,在此不再貼源碼了,有興趣的可以自行查看。
從window中的方法setWindowManager中可以看出建立的WindowManager的對象實際上是WindowManagerImpl,此類是WindowManager的實作類別,源碼如下:
public final class WindowManagerImpl implements WindowManager { private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); private final Display mDisplay; private final Window mParentWindow; public WindowManagerImpl(Display display) { this(display, null); } private WindowManagerImpl(Display display, Window parentWindow) { mDisplay = display; mParentWindow = parentWindow; } public WindowManagerImpl createLocalWindowManager(Window parentWindow) { return new WindowManagerImpl(mDisplay, parentWindow); } public WindowManagerImpl createPresentationWindowManager(Display display) { return new WindowManagerImpl(display, mParentWindow); } @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); } @Override public void removeViewImmediate(View view) { mGlobal.removeView(view, true); } @Override public Display getDefaultDisplay() { return mDisplay; }}
該實作類別比較簡單,主要持有Window類型的mParentWindow對象,並提供一系列的方法用於構建WindowManagerImpl對象,其他方法的實現主要調用WindowManagerGlobal對象中的回應程式法。
在window的setWindowManager方法主要調用了WindowManagerImpl的createLocalWindowManager建立了WindowManager對象,這樣就將Window和WindowManager關聯起來了,也就意味在調用WindowManager的addView、updateViewLayout、removeView時實際上操作的是Window內部的View,這一點可以通過查看WindowManagerGlobal相關方法的源碼可以看出。
疑問諮詢或技術交流,請加入官方QQ群: (452379712)
作者:傑瑞教育
出處:http://www.cnblogs.com/jerehedu/
本文著作權歸煙台傑瑞教育科技有限公司和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。