Android之WindowManager介紹

image.png

目錄

Android之WindowManager介紹

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);
        ……
    }

image.png

代碼中會調(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。

image.png

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 {}
image.png
image.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市狱意,隨后出現(xiàn)的幾起案子湖苞,更是在濱河造成了極大的恐慌,老刑警劉巖详囤,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件财骨,死亡現(xiàn)場離奇詭異,居然都是意外死亡藏姐,警方通過查閱死者的電腦和手機隆箩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羔杨,“玉大人捌臊,你說我怎么就攤上這事《挡模” “怎么了理澎?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長曙寡。 經(jīng)常有香客問我糠爬,道長,這世上最難降的妖魔是什么举庶? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任执隧,我火速辦了婚禮,結果婚禮上户侥,老公的妹妹穿的比我還像新娘镀琉。我一直安慰自己,他們只是感情好添祸,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布滚粟。 她就那樣靜靜地躺著寻仗,像睡著了一般刃泌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天耙替,我揣著相機與錄音亚侠,去河邊找鬼。 笑死俗扇,一個胖子當著我的面吹牛硝烂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铜幽,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼滞谢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了除抛?” 一聲冷哼從身側響起狮杨,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎到忽,沒想到半個月后橄教,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡喘漏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年护蝶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翩迈。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡持灰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出负饲,到底是詐尸還是另有隱情搅方,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布绽族,位于F島的核電站姨涡,受9級特大地震影響,放射性物質發(fā)生泄漏吧慢。R本人自食惡果不足惜涛漂,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望检诗。 院中可真熱鬧匈仗,春花似錦、人聲如沸逢慌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攻泼。三九已至火架,卻和暖如春鉴象,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背何鸡。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工纺弊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骡男。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓淆游,卻偏偏與公主長得像,于是被迫代替她去往敵國和親隔盛。 傳聞我的和親對象是個殘疾皇子犹菱,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355