源碼分析閱讀 - Window底層原理與系統(tǒng)架構(gòu)

1. 說明


今天我們來看下Window底層原理太抓,這個就要求我們必須對下邊的知識要非常之清楚:
當app一運行到手機上邊時乙埃,我們一定要清楚的知道:
一定要在心里面對FrameWork層的源碼有一個架構(gòu)吱窝、Activity是怎么啟動的、布局文件是怎樣加載的夷野、資源怎么加載的、View的繪制流程荣倾、View的Touch事件悯搔、IPC進程間通信機制、Handler源碼分析

2. 分析


我們一開始開發(fā)時可能聽的最多的就是四大組件舌仍,那么到后期可能就會聽到AMS以及其他的一些名詞妒貌,那么我們就來看下這些都代表什么意思?

AMS:指的是 ActivityManagerService 有Activity、ActivityManager铸豁;
WMS(窗口有關(guān)):Window灌曙、WindowManager、WindowManagerService节芥、Token在刺、Session、ViewRootImpl头镊、View(我們就只是講了DecorView)

當面試如果問你AMS和WMS是怎樣建立聯(lián)系的蚣驼,也就是說Activity、View相艇、Window之間的聯(lián)系是怎樣的颖杏?
回答:
其實ActivityManagerService和WindowManagerService的設(shè)計模式以及它們的設(shè)計風(fēng)格其實是差不太多的,都是跨進程之間的通訊的坛芽,AMS有Activity留储、ActivityManager、ActivityManagerService咙轩,而WMS中有Window获讳、WindowManager、WindowManagerService活喊,只不過WMS中有Token赔嚎、Session、ViewRootImpl(DecorView是根布局)

Activity中有PhoneWindow胧弛,PhoneWindow中有一個根布局DecorView,會首先給WindowManager侠畔,然后WindowManager其實什么都沒做结缚,它是交給WindowManagerGlobal這個單例來統(tǒng)一去管理,因為只有單例才適合去做我們的管理類软棺,原因就是 單例是一直存在于我們的內(nèi)存中红竭,不會隨著Activity的退出而銷毀。而DecorView傳遞到WindowManagerGlobal之后,它會去創(chuàng)建ViewRootImpl ,即就是ViewRoot的實現(xiàn)類茵宪,ViewRootImpl這個實現(xiàn)類有2個作用:
第一個就是和遠程的WindowManagerService進行通信的最冰,會首先從遠程的服務(wù)端中去獲取session來通信,因為我們應(yīng)用無法操作系統(tǒng)的布局稀火,比如說點擊輸入法暖哨,就需要通知系統(tǒng)讓輸入法彈起來,所以只能通過這樣的方式來進行通信凰狞;
第二個就是與View的繪制流程 篇裁;

那么我們接下來就來看下app剛運行到手機上邊時,我們都做了哪些工作赡若?

2.1 當手機剛一運行app時候調(diào)用setContentView() ->

2.2 Activity里邊有PhoneWindow 达布,調(diào)用PhoneWindow設(shè)置setContentView()布局 ,而setContentView()方法中就是去創(chuàng)建一個根View逾冬,即就是DecorView 黍聂,然后加載系統(tǒng)默認的布局,然后解析我們設(shè)置的資源布局添加到android.R.id.content中身腻,也就是添加到ContentParent中产还。PhoneWindow的setContentView()這個方法執(zhí)行完畢后只是去解析加載我們的布局,即就是activity_main.xml文件霸株,然后什么都沒干->
那么我們自己的activity_main.xml的布局文件是怎樣顯示出來的呢雕沉??去件?

3. 布局的顯示繪制流程


Activity中的源碼坡椒,里邊有一個PhoneWindow:

final void attach(Context context, ActivityThread aThread,
        mWindow = new PhoneWindow(this, window);

PhoneWindow中的源碼,里邊有一個setContentView()方法:

@Override
    public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

3.1 activity_main.xml布局文件是怎樣顯示出來的尤溜?

Activity中的attach()方法倔叼,會綁定設(shè)置Activity的一些參數(shù),Activity里邊有一個PhoneWindow宫莱,即就是new PhoneWindow() 丈攒,Window里面有一個WindowManager

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) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

Activity是通過反射創(chuàng)建出來的,在ActivityThread中的performLaunchActivity()方法中

WindowManager.LayoutParams 和RelativeLayout.LayoutParams差不多授霸,而RelativeLayout.LayoutParams是用來描述布局的一些信息的巡验,意思就是:

比如在activity_main.xml布局文件中有一個TextView,如果你的根布局是RelativeLayout碘耳,并且給TextView設(shè)置了
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
那么對于TextView是有作用的显设;
如果你的根布局是LinearLayout的話,那么設(shè)置這兩個屬性就沒有作用辛辨,因為LinearLayout源碼中就沒有定義這兩個屬性捕捂,就像RelativeLayout源碼中沒有定義
android:layout_gravity="center"
android:gravity="center"
這兩個屬性一樣瑟枫。

3.2 wm.addView(decor , 1);

這個方法在布局的繪制流程中看過指攒,WindowManager的實現(xiàn)類是WindowManagerImpl慷妙,實際上調(diào)用的是WindowManagerGlobal,而WindowManagerGlobal是一個單例允悦,單例設(shè)計模式意思就是一直在我們的內(nèi)存中膝擂,不會隨著Activity的退出而銷毀,而我們項目中肯定有很多的Activity澡屡,也會對應(yīng)的有很多的布局文件猿挚,所以它就會去管理Activity,而且像一些管理類都是單例

findViewLocked(view 驶鹉, false)绩蜻;意思就是如圖所示:
Activity1、Activity2都會去調(diào)用setContentView()方法室埋,而且他們都會有一個DecorView办绝,而這兩個Activity都是由 WindowManagerGlobal這個單例來管理

ViewRootImpl


總結(jié)布局文件繪制流程順序如下
activity ->
PhoneWindow(DecorView) ->
WindowManager(不是單例,所以有多個) ->
WindowManagerGlobal(是單例姚淆,只有1個) ->
ViewRootImpl(有多個孕蝉,但是一個ViewRootImpl只會綁定一個DecorView)

也就是說:
activity里邊有一個PhoneWindow ->
PhoneWindow里邊有一個DecorView ,DecorView最終是交給一個全局變量去管理的腌逢,而這個全局變量中就存儲了很多的變量降淮,有ViewRootImpl ->
而ViewRootImpl是用來和遠程服務(wù)去通信的 ->
頁面是交給WindowManagerGlobal這個單例類去管理的

跨進程通信就意味著:app應(yīng)用和系統(tǒng)服務(wù)一定要建立連接

4. requestLayout()方法 —— 百度、阿里搏讶、騰訊等等大公司都會必問的一個問題


是View繪制流程的入口佳鳖,在這個方法中做了3件事
performMeasure()、performLayout()媒惕、performDraw()系吩,測量、擺放妒蔚、繪制
這個很重要穿挨,百度、阿里肴盏、騰訊等等大公司都會必問的一個問題科盛,就是View的繪制流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市菜皂,隨后出現(xiàn)的幾起案子土涝,更是在濱河造成了極大的恐慌,老刑警劉巖幌墓,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件但壮,死亡現(xiàn)場離奇詭異,居然都是意外死亡常侣,警方通過查閱死者的電腦和手機蜡饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胳施,“玉大人溯祸,你說我怎么就攤上這事∥杷粒” “怎么了焦辅?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長椿胯。 經(jīng)常有香客問我筷登,道長,這世上最難降的妖魔是什么哩盲? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任前方,我火速辦了婚禮,結(jié)果婚禮上廉油,老公的妹妹穿的比我還像新娘惠险。我一直安慰自己,他們只是感情好抒线,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布班巩。 她就那樣靜靜地躺著,像睡著了一般嘶炭。 火紅的嫁衣襯著肌膚如雪抱慌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天旱物,我揣著相機與錄音遥缕,去河邊找鬼。 笑死宵呛,一個胖子當著我的面吹牛单匣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宝穗,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼户秤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逮矛?” 一聲冷哼從身側(cè)響起鸡号,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎须鼎,沒想到半個月后鲸伴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體府蔗,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年汞窗,在試婚紗的時候發(fā)現(xiàn)自己被綠了姓赤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡仲吏,死狀恐怖不铆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裹唆,我是刑警寧澤誓斥,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站许帐,受9級特大地震影響劳坑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舞吭,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一泡垃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羡鸥,春花似錦蔑穴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至衷旅,卻和暖如春捐腿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柿顶。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工茄袖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘁锯。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓宪祥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親家乘。 傳聞我的和親對象是個殘疾皇子蝗羊,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容