Activity Window View-[Android_YangKe]

轉載請注明 Android_YangKe,謝謝饶辙!

老實說自己做 Android 有一段時間了耳幢,但發(fā)現(xiàn) Android 技能提升上有了點小瓶頸,總感覺自己什么都會禁悠,又都感覺自己什么都不會念祭,于是就有了此片文章。

下面我們將通過 Window 慢慢引出三者之間的關系碍侦,同時適當?shù)脑创a輔助分析粱坤。說到源碼相信很多人都是心中都一萬個 mmb,勞資這么差的英文瓷产,動不動成千上萬行的代碼站玄,腦袋瞬間短路好不好... 微笑-微笑 。

Activity濒旦,View 是什么我相信不用解釋株旷,而 Window 在使用頻率上相對來說就低了些,那么 Window 是什么尔邓?在 Android 體系中扮演著什么樣的角色晾剖?下面是 Google 工程師對 Window 類的一些介紹,我們來看下铃拇。

//Window.java
/**
 * Abstract base class for a top-level window look and behavior policy.  An
 * instance of this class should be used as the top-level view added to the
 * window manager. It provides standard UI policies such as a background, title
 * area, default key processing, etc.
 *
 * <p>The only existing implementation of this abstract class is
 * android.view.PhoneWindow, which you should instantiate when needing a
 * Window.
 */

大致意思:Window 是一個基礎類钞瀑,是頂級視圖的承載。提供了標準的 UI 策略慷荔,如背景雕什,標題。同時 Window 只有一個實現(xiàn)類PhoneWindow显晶。官方的解釋還是比較給力贷岸,很詳細的介紹了該對象,現(xiàn)在我們對 Window 有了一個初步認識磷雇。下面我們將結合具體案例進行探索偿警。

Activity 中 onCreate 函數(shù)相信大家再熟悉不過了,如我們將里面的setContentView函數(shù)注釋掉時唯笙,會發(fā)現(xiàn)原來我們的炫酷的頁面只留下一個標題加空白頁面(前提我們沒有修改默認的主題)螟蒸,這么看來此行代碼很關鍵盒使。

//Activity.java
public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

一般來說我們的 Activity 都是繼承自 AppCompatActivity,但最終的頂層父類是 Activity七嫌。通過上面源碼我們可以發(fā)現(xiàn) Activity 只是 View 宿主少办,并沒有真正的實現(xiàn)setContentView而是通過 getWindow 操作此函數(shù),我們來看下 getWindow诵原。

//Activity.java
public Window getWindow() {
    return mWindow;
}
final void attach(...) {
    attachBaseContext(context);
    mWindow = new PhoneWindow(this, window,activityConfigCallback);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    ...
}

很簡單 getWindow 函數(shù)返回了一個實例PhoneWindow英妓。由于代碼中沒有對 getWindow 判空,我們可以推測出 attach 函數(shù)一定在 setContentView 之前執(zhí)行绍赛,也就是 onCreate 函數(shù)之前蔓纠,不然一定會報NullPointerException

扯得有點多吗蚌,言歸正傳腿倚。這里我們看到了 Window 的身影,從上文我們了解到 Window 是頂級視圖的承載褪测,而PhoneWindow又是 Window 的唯一子類猴誊,我們嘗試著去 PhoneWindow中探索 setContentView

//PhoneWindow.java

// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
ViewGroup mContentParent;

public void setContentView(View view, ViewGroup.LayoutParams params) {
    if (mContentParent == null) {
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }
    ...
}

一大串代碼(當然我省略了一部分代碼)果不其然侮措,真正的操作的就是在 Window 的 setContentView函數(shù)中完成的,首先乖杠。

  • mDecor:Window 上最頂層的視圖分扎,如果按照從上到下的順序,分別是狀態(tài)欄胧洒,標題欄畏吓,具體 View 控件。由于其繼承了 FrameLayout 也就是說 mDecor 也是一個 ViewGroup卫漫。
  • mContentParent:表示視圖區(qū)域菲饼,里面可以是 mDecor,也可以是 mDecor 中的具體 View列赎,但不代表具體視圖宏悦。

了解了這兩個對象的作用,我們繼續(xù)看代碼包吝。removeAllViews函數(shù)顧名思義饼煞,也就是從當前 Window 中移除所有 View,這里就不進入源碼進行分析了(代碼水很深诗越,隨時保留精氣神)∽┣疲現(xiàn)在就剩下installDecor了,此函數(shù)貌似很關鍵嚷狞,我們跟進來看下块促。

//PhoneWindow.java
private void installDecor() {
    if (mDecor == null) {
        mDecor = generateDecor(-1);
        ...
    } else {
        mDecor.setWindow(this);
    }
    if (mContentParent == null) {
        mContentParent = generateLayout(mDecor);
    ...
    }
}

首先映入眼簾的是generateDecor荣堰,同時此函數(shù)的返回值賦予了 mDecor。隨后系統(tǒng)調用了generateLayout竭翠。generateLayout從字面意義上來看是初始化布局持隧,莫非跟布局 View 有關,我們來看一下逃片。

//PhoneWindow.java
protected ViewGroup generateLayout(DecorView decor) {
 // Apply data from current theme.
 TypedArray a = getWindowStyle();
 if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
     requestFeature(FEATURE_NO_TITLE);
 } else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
     // Don't allow an action bar if there is no title.
     requestFeature(FEATURE_ACTION_BAR);
 }
 if (a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
     setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
 }
 ...
}      

這里我們拋去 if 的各種判斷直接看這幾個常量:FLAG_FULLSCREEN屡拨、 FEATURE_NO_TITLEFLAG_FULLSCREEN等等褥实,是不是似曾相識呢呀狼?相信大家在 onCreate 函數(shù)setContentView前都有過重設當前 Activity 樣式的經(jīng)歷,嚴格來說應該是 Window (Activity 全屏损离、去除標題欄)哥艇。也就是說屏幕上頁面的尺寸,樣式都是通過 Window 來控制的僻澎!看來此函數(shù)很重要貌踏,打起精神,我們再來分析一波窟勃。

//PhoneWindow.java
protected ViewGroup generateLayout(DecorView decor) {
    // Remaining setup -- of background and title -- that only applies
    // to top-level windows.

    WindowManager.LayoutParams params = getAttributes();
    if (!hasSoftInputMode()) {
        params.softInputMode = a.getInt(R.styleable.Window_windowSoftInputMode, params.softInputMode);
    }
    if (params.windowAnimations == 0) {
        params.windowAnimations = a.getResourceId(R.styleable.Window_windowAnimationStyle, 0);
    }
    ...
    if (getContainer() == null) {
        final Drawable background;
        if (mBackgroundResource != 0) {
            background = getContext().getDrawable(mBackgroundResource);
        } else {
            background = mBackgroundDrawable;
        }
        mDecor.setWindowBackground(background);

        final Drawable frame;
        if (mFrameResource != 0) {
            frame = getContext().getDrawable(mFrameResource);
        } else {
            frame = null;
        }
        mDecor.setWindowFrame(frame);
        ...
        if (mTitle != null) {setTitle(mTitle);}
        if (mTitleColor == 0) {mTitleColor = mTextColor;}
        setTitleColor(mTitleColor);
    }
    mDecor.finishChanging();

    return contentParent;
}

首先我們看下官方給的注釋:

  • Remaining setup -- of background and title -- that only applies to top-level windows.

將自己置身于情境之中祖乳,大概意思:設置標題,背景顏色秉氧,將視圖應用在頂層 View 上眷昆,誰呢?DecorView汁咏。

其次:
獲取 Window 的一些屬性亚斋,并根據(jù)情況對輸入法模式、載入動畫等等進行配置攘滩。

最后:
對 Window 承載的視圖進行背景設置帅刊,邊距設置,標題欄顏色設置漂问,標題欄設置等等赖瞒。

到這里相信你對 Window 的作用,以及其在 Android 中扮演著怎樣的角色有了一定的認知级解。下面我們來看一張圖片冒黑,輔助我們理解 Activity、Window勤哗、View 之間的關系:(圖片源自互聯(lián)網(wǎng)抡爹,出處不明)

yangke.png

最外層是 Activity、其次是 PhoneWindow芒划、最后是我們常操作的 View 控件冬竟。通過這張圖相信你對 Activity欧穴、Window、View 有了進一步的認識泵殴,下面我們再來重新認識下三者涮帘。

View:說到 View 相信大家都很熟悉,像什么 TextView笑诅、Button调缨、ImageView 等等我相信你可以一口氣說一大堆。View 是具體視圖的最小展示單元吆你。在頁面上可以是一張圖片弦叶,一段文本,一個網(wǎng)頁妇多。簡而言之:View 就是具體視圖(常常與用戶打交道)伤哺。

Window:我們真正意義上所說的頁面,是 Activity 任命的大使者祖,主要用于管理 View立莉,設置窗口(視圖)樣式、尺寸七问、輸入法模式等蜓耻。我們也可以通過WindowManager對 View 進行添加和移除操作等。簡而言之:Window 主要用于控制顯示窗口的尺寸烂瘫、樣式媒熊、View 的移除添加(常常與研發(fā)人員打交道)。

Activity:頁面的載體坟比。維護應用程序的生命周期、提供用戶處理事件的 API嚷往、進程間通信等葛账。簡而言之:用于管理系統(tǒng)組件相關事物。

整理:
Activity-> PhoneWindow-> DecorView皮仁。

總結:
Activity 作為四大組件主要與系統(tǒng)進行交互籍琳,用于組件間通信,生命周期管理贷祈、進程通信等趋急。Window 作為視圖載體,主要用于管理視圖的尺寸势誊、樣式呜达、輸入法模式、View 的移除添加等粟耻,需要依托于 Activiity查近。View 就比較簡單了眉踱,不同的 View 用于展示不同的視圖,例:文本組件霜威,圖片組件谈喳,甚至網(wǎng)頁等,需要依托于 Window戈泼。也就是說三者相輔相成婿禽,誰離開都將無存在意義。

尾聲:
為什么 View 不直接與 Activity 關聯(lián)呢大猛?反而又設計出一個 Window 對象扭倾?

其實這里有些面向對象的概念,也就是說對于龐大的功能我們需要進行拆分胎署,讓其盡量獨立吆录,各司其職,同時在功能互不影響的情況下琼牧,相輔相成恢筝。

完~

喜歡有幫助的話: 雙擊、評論巨坊、轉發(fā)撬槽,動一動你的小手讓更多的人知道!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末趾撵,一起剝皮案震驚了整個濱河市侄柔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌占调,老刑警劉巖暂题,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異究珊,居然都是意外死亡薪者,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門剿涮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來言津,“玉大人,你說我怎么就攤上這事取试⌒郏” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵瞬浓,是天一觀的道長初婆。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么烟逊? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任渣窜,我火速辦了婚禮,結果婚禮上宪躯,老公的妹妹穿的比我還像新娘乔宿。我一直安慰自己,他們只是感情好访雪,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布详瑞。 她就那樣靜靜地躺著,像睡著了一般臣缀。 火紅的嫁衣襯著肌膚如雪坝橡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音,去河邊找鬼聪姿。 笑死允扇,一個胖子當著我的面吹牛啤挎,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蝶押!你這毒婦竟也來了?” 一聲冷哼從身側響起火欧,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棋电,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苇侵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赶盔,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年榆浓,在試婚紗的時候發(fā)現(xiàn)自己被綠了招刨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡哀军,死狀恐怖,靈堂內的尸體忽然破棺而出打却,到底是詐尸還是另有隱情杉适,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布柳击,位于F島的核電站猿推,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蹬叭,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一藕咏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧秽五,春花似錦孽查、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瓣铣,卻和暖如春答朋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棠笑。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工梦碗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蓖救。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓洪规,卻偏偏與公主長得像,于是被迫代替她去往敵國和親藻糖。 傳聞我的和親對象是個殘疾皇子淹冰,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容