目錄
WindowManager
android中真正展示給用戶的是window和view.
activity在android中所其的作用主要是處理一些邏輯問題晒旅,比如生命周期的管理画机、建立窗口等劣领。
在android中,窗口的管理還是比較重要的一塊固逗,因為他直接負責把內(nèi)容展示給用戶,并和用戶進行交互广辰。響應用戶的輸入等查邢。
WindowManager繼承自ViewManager,里面涉及到窗口管理的三個重要方法我擂,分別是:
* addView();
* updateViewLayout();
* removeView();
Window
android的窗口分為三種:
1衬以、應用程序窗口 (Application Window): 包括所有應用程序自己創(chuàng)建的窗口,以及在應用起來之前系統(tǒng)負責顯示的窗口校摩。
2看峻、子窗口(Sub Window):比如應用自定義的對話框,或者輸入法窗口衙吩,子窗口必須依附于某個應用窗口(設置相同的token)互妓。
3、系統(tǒng)窗口(System Window): 系統(tǒng)設計的坤塞,不依附于任何應用的窗口车猬,比如說,狀態(tài)欄(Status Bar), 導航欄(Navigation Bar), 壁紙(Wallpaper), 來電顯示窗口(Phone)尺锚,鎖屏窗口(KeyGuard), 信息提示窗口(Toast)珠闰, 音量調(diào)整窗口,鼠標光標等等瘫辩。
Window.java 是個虛類:
public abstract class Window {}
他的具體實現(xiàn)是 PhoneWindow.java 伏嗜。
PhoneWindow對象被創(chuàng)建是在Activity中:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback) {
attachBaseContext(context);
……
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
……
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
……
}
代碼中會調(diào)用PhoneWindow的setWindowManager函數(shù)(實現(xiàn)在Windows類中):
public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {
setWindowManager(wm, appToken, appName, false);
}
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);
}
這里看到會執(zhí)行WindowManagerImpl.java的createLocalWindowManager函數(shù):
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);
}
所以最后mWindowManager 保存了一個local的WindowManager.
之前傳進來的WindowManagerImpl實例又去創(chuàng)建了一個具有ParentWindow的WindowManagerImpl實例,根據(jù)他的參數(shù)可以看出伐厌,這里的Window是作為WindowManagerImpl的parentWindow的承绸,也就是他們倆的關系從表面看上去好像是父級和子級的層級關系。
WindowManager的功能介紹
Window是一個抽象的概念挣轨,每一個Window都對應著一個View和一個ViewRootImpl军熏,Window和View通過ViewRootImpl來建立聯(lián)系,說明View才是Window存在的實體卷扮,在實際使用中無法直接訪問Window荡澎,對Window的訪問必須通過WindowManager。
Window的添加過程需要通過WindowManager的addView來實現(xiàn)晤锹,WindowManager是一個接口摩幔,它的真正實現(xiàn)是WindowManagerImpl類。
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
mGlobal是WindowManagerGlobal:
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
WindowManager操作Window鞭铆,不過具體的實現(xiàn)細節(jié)還是WindowManagerGlobal這個類來做的或衡,這個類是一個單例模式。
繼續(xù)看下WindowManagerGlobal.java的addView函數(shù):
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
……
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
// 界面布局的限制
parentWindow.adjustLayoutParamsForSubWindow(wparams);
} else {
final Context context = view.getContext();
if (context != null
&& (context.getApplicationInfo().flags
& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
……
// 構建界面控制
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
//將View顯示到手機窗口
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
其中創(chuàng)建了ViewRootImpl 。
ViewRootImpl 是一個視圖層次結構的頂部封断,ViewRootImpl 實現(xiàn)了 View 與 WindowManager 之間所需要的協(xié)議斯辰,作為 WindowManagerGlobal 中大部分的內(nèi)部實現(xiàn)。
在 WindowManagerGlobal 中實現(xiàn)方法中坡疼,都可以見到 ViewRootImpl椒涯,也就說 WindowManagerGlobal 方法最后還是調(diào)用到了 ViewRootImpl。
比如addView回梧,removeView废岂,update 的調(diào)用順序:WindowManagerImpl -> WindowManagerGlobal -> ViewRootImpl.
而且WindowManager.java 是繼承的ViewManager .
public interface WindowManager extends ViewManager {}