動腦學(xué)院UI預(yù)習(xí)資料-UI繪制流程詳解

前言

在android當(dāng)中對于UI體系當(dāng)中往往我們會在繪制UI的時候碰到各種各樣的問題而不知道從何解決着裹, 也有時需要開發(fā)更改自定義組件時,需要做自己的調(diào)整瑰妄,或者是實現(xiàn)某個自定義特效時的思路不明確陷嘴,想要達到去玩轉(zhuǎn)UI的最為基礎(chǔ)的部分,就是去全面的深入了解UI的繪制流程.所以接下來帶大家去進行全面分析UI整體的繪制體系.

思路:android程序啟動--->Activity加載并完成生命周期--->setContentView--->圖形繪制

疑惑:

1.Android程序是如何啟動,Activity生命周期如何調(diào)用翰撑?

2.在Activity onCreate當(dāng)中我們的setContentView是如何將UI文件加載罩旋?

3.UI是如何繪制的啊央?

答案:

1.Android程序流程

眾所周知,我們的java程序想要開啟需要依賴于main方法涨醋,也就是我們的程序入口(主線程)進入瓜饥,但是在我們?nèi)粘i_發(fā)android程序的過程當(dāng)中我們并沒有發(fā)現(xiàn)main方法的存在,那么android當(dāng)中的是如何開始運行的浴骂?

熟悉的朋友們可能都知道在android當(dāng)中存在一個叫做ActivityThread的類乓土,這個類代表的是android當(dāng)中的主線程,而在這個類當(dāng)中我們看到了比較熟悉的main方法溯警,那么現(xiàn)在是否可以認為我們的android在打開app時是首先調(diào)用的是當(dāng)前這個類的main趣苏,也就是此處為我們的啟動點

圖1

在此處可以看到Activity調(diào)用了一個attach()方法

圖2

在這里我們可能首先要考慮的是getService拿出來的是什么?

進去之后梯轻,我們會發(fā)現(xiàn)

圖3

在這個當(dāng)中食磕,里面調(diào)用了的系統(tǒng)的ActivityManagerService這個服務(wù),并且給出了一個Binder接口

那么在這里喳挑,我們可以聯(lián)想到彬伦,在android當(dāng)中的binder通信機制,那么實際上我們的ActivityManager是有系統(tǒng)服務(wù)所調(diào)用管理伊诵,并且通過在binder接口當(dāng)中進行調(diào)用单绑,這也是為什么我們講Activity是跨進程訪問的原因

圖4

那么明白了這個時候能夠得到ActivityManager之后,我們接著回到attach當(dāng)中繼續(xù)看下去曹宴, 這個時候會發(fā)現(xiàn)搂橙,我們調(diào)用了一個attachApplication方法(見圖2)這個方法又是干嘛的?attachApplication在這里的作用其實實際上是ActivityThread通過attach獲取到笛坦,然后將applciationThread將其關(guān)聯(lián)区转,把activity相關(guān)信息存儲在applciationThread里面,apllicationThread的類為activity的各種狀態(tài)做了相對應(yīng)的準備工作

圖5

這個時候我們需要關(guān)注弯屈,ApplicationThread當(dāng)中做了什么蜗帜?

當(dāng)我們打開ApplicationThread中我們會看到一堆的schedle方法,這些方法的名稱其實就可以給我們表明资厉,代表的是在執(zhí)行Activity的某種狀態(tài)時調(diào)用的計劃執(zhí)行方法

這時我們會看到一個scheduleLaunchActivity方法,表示計劃加載時調(diào)用的

這里我門發(fā)現(xiàn)了一個很有意思的事情

圖6
圖7

這個上面我們會看到一個ActivityClientRecord對象蔬顾,這個對象其實實際上就是我們的Activity

而且似乎每一個方法還干了一件讓我們非常熟悉的一件事宴偿, 進行了一次sendMessage()將當(dāng)前創(chuàng)建的Activity發(fā)送了出去

圖8

當(dāng)走到這里我們會發(fā)現(xiàn)最終我們調(diào)用的是Handler的消息通信機制,也就是說诀豁,在這里我們可以總結(jié)一下窄刘,

當(dāng)Activity狀態(tài)改變時,都會有對應(yīng)的一個消息發(fā)送出去

而接收這里舷胜,我能發(fā)現(xiàn)通過發(fā)送時不同的狀態(tài)娩践,這邊調(diào)用了不同的handlerXXXActivity方法

圖9

在這里,我門貌似發(fā)現(xiàn)了Activity的生命周期的調(diào)用痕跡,那么其實到此為止翻伺,我門可以得出一個結(jié)論材泄,

Application運行的過程當(dāng)中,對于Activity的操作吨岭,狀態(tài)轉(zhuǎn)變拉宗,其實實際上是通過Handler消息機制來完成的,

Application當(dāng)中只管去發(fā)辣辫, 由消息機制負責(zé)調(diào)用旦事,因為在main方法當(dāng)中我門的Looper輪訓(xùn)器是一直在進行輪訓(xùn)的

而當(dāng)我們在加載Activity的時候,當(dāng)中調(diào)用了一個performLaunchActivity()方法急灭,在這個中間我發(fā)現(xiàn)了我們onCreate的調(diào)用痕跡

圖10

也就是說姐浮,到目前為止我們能夠明白,整個Application加載Activity的整套流程是怎么回事

那么接下來我們需要關(guān)注的是葬馋,在onCreate當(dāng)中我們所寫的setContentView到底干了什么

2.setContentView

在onCreate當(dāng)中我們往往會使用setContentView去進行設(shè)置我們自己的布局文件或者view单料,那么在這當(dāng)中他到底是怎么做的?通過觀察源碼点楼,這個時候通過一系列線索我找到了最終的位置PhoneWindow類

圖11

這個時候我們會看到他做了兩個事情扫尖,一個是installDecor,另一個是inflate掠廓,這兩個后一個不難猜出他是在進行布局文件的解析换怖, 前面的我們認為她是在初始化某個東西

圖12

進來之后發(fā)現(xiàn)他初始化了兩個東西,一個叫做mDecor,一個叫做mContentParent

圖13
圖14

我們看到了mDecor是一個DecorView

mContentParent是一個ViewGroup

透過注釋的翻譯蟀瞧,其實我們就能很明確知道這兩個是用來干嘛的

// This is the view in which the window contents are placed. It is either(這是窗口內(nèi)容放置的視圖)

// mDecor itself, or a child of mDecor where the contents go.(它要么是mDecor本身沉颂,要么是mDecor的子類的內(nèi)容。)

//This is the top-level view of the window, containing the window decor.(這是在窗口當(dāng)中的頂層View悦污,包含窗口的decor)

一個代表的是頂層view铸屉,一個用來裝他下面的視圖內(nèi)容

在接著往下看的時候,我門發(fā)現(xiàn)切端,generateLayout方法當(dāng)中彻坛,發(fā)現(xiàn)了在此處進行了大量的requestFeature的調(diào)用,也就是所踏枣,我們的requestFeature

圖15

然后在下面我門會發(fā)現(xiàn)在做了一件事情昌屉,

圖16
圖17
圖18

當(dāng)前這里竟然在加載布局文件,并且生成了一個view茵瀑, 但是好像貌似不是我門自己的

所以我們需要去探尋他到底加載了一個什么東東间驮?

圖19

這是我找到了一個比較有意思的組件,

在這個上面我看到了一句這樣的注釋

//This is an optimized layout for a screen, with the minimum set of features

enabled.

這是一個屏幕的優(yōu)化布局马昨,具有最小的特征集啟用竞帽。

通過注釋和一些資料分析扛施, 得到了一個比較坑的結(jié)果。

圖20

這是DecorView默認的一個渲染屹篓,然后我門自己的布局都是渲染到她的FrameLayout上的

那么在這里我門現(xiàn)在能夠明白疙渣,installDector其實實際上是在初始化兩個視圖容器,然后加載系統(tǒng)的R資源及特征抱虐,產(chǎn)生了一個基本布局

那么接著回到之前我門關(guān)注的另外一個方法mLayoutInflater.inflate(layoutResID, mContentParent);

這個方法就比較好理解了昌阿,

圖21

這這段注釋上面我門就可以得到一個信息

//Inflate a new view hierarchy from the specified xml resource.(從指定的視圖當(dāng)中獲取試圖的層次結(jié)構(gòu),意思就是恳邀,現(xiàn)在在加載自己的資源)

而具體流程就不貼代碼了給各位上一張圖

圖22

那么在這里我門就能夠明白懦冰,setContentView其實做了兩件比較核心的事情,就是加載環(huán)境配置谣沸,和自己的布局刷钢,那么接下來我門需要考慮的事情就是,他到底怎么畫到界面上的

3.UI是如何繪制的乳附?

通過前面兩個章節(jié)内地,我門了解到,程序?qū)τ赼ctivity生命周期的調(diào)用赋除,以及我們的視圖資源的由來阱缓。這是我門需要找到的是我門的繪制起點在哪?

圖23

在ActivityThread啟動時举农, 我發(fā)現(xiàn)在加載handleLaunchActivity方法調(diào)用performLaunchActivity方法之后又調(diào)用了一個handleResumeActivity在這里我發(fā)現(xiàn)了繪制流程的開始

圖24

通過前面的流程我門知道荆针,onCreate之行完成之后,所有資源交給WindowManager保管

在這里颁糟,將我們的VIew交給了WindowManager,此處調(diào)用了addView

圖25
圖26
圖27

進入addView之后我們發(fā)現(xiàn)了一段這樣的代碼航背,他將視圖,和參數(shù)還有我門的一個ViewRoot對象都用了容器去裝在了起來棱貌,那么在此處我門可以得出玖媚,是將所有的相關(guān)對象保存起來

mViews保存的是View對象,DecorView

mRoots保存和頂層View關(guān)聯(lián)的ViewRootImpl對象

mParams保存的是創(chuàng)建頂層View的layout參數(shù)婚脱。

而WindowManagerGlobal類也負責(zé)和WMS通信

而在此時今魔,有一句關(guān)鍵代碼root.setView,這里是將我們的參數(shù)起惕,和視圖同時交給了ViewRoot涡贱,那么這個時候我們來看下ViewRoot當(dāng)中的setView干了什么

終于在這里讓我發(fā)現(xiàn)了讓我明白的一步

圖28

在這里我門會看到view.assignParent的設(shè)置是this, 那么也就是說在view當(dāng)中parent其實實際上是ViewRoot

那么在setContentView當(dāng)中調(diào)用了一個setLayoutParams()是調(diào)用的ViewRoot的

而在ViewRoot當(dāng)中發(fā)現(xiàn)了setLayoutParams和preformLayout對requestLayout方法的調(diào)用

在requestLayout當(dāng)中發(fā)現(xiàn)了對scheduleTraversals方法的調(diào)用而scheduleTraversals當(dāng)中調(diào)用了doTraversal的訪問惹想,最終訪問到了performTraversals(),而在這個里面督函,我發(fā)現(xiàn)了整體的繪制流程的調(diào)用

當(dāng)前里面依次是用了

圖29
圖30
圖31

UI繪制先回去測量布局嘀粱,然后在進行布局的擺放激挪,當(dāng)所有的布局測量擺放完畢之后,進行繪制锋叨。

至此整體UI繪制過程我們就已經(jīng)非常清楚了垄分。

我門可以根據(jù)這種繪制的流程來操作自己的自定義組件。

作者:動腦學(xué)院Barry老師
原創(chuàng)博客娃磺,請注明轉(zhuǎn)載處....
鏈接:http://www.reibang.com/p/0f6b4bc86c7b
來源:簡書(昵稱BarryKerwin)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末薄湿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偷卧,更是在濱河造成了極大的恐慌豺瘤,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件听诸,死亡現(xiàn)場離奇詭異坐求,居然都是意外死亡,警方通過查閱死者的電腦和手機晌梨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門桥嗤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仔蝌,你說我怎么就攤上這事泛领。” “怎么了敛惊?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵渊鞋,是天一觀的道長。 經(jīng)常有香客問我豆混,道長篓像,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任皿伺,我火速辦了婚禮员辩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鸵鸥。我一直安慰自己奠滑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布妒穴。 她就那樣靜靜地躺著宋税,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讼油。 梳的紋絲不亂的頭發(fā)上杰赛,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音矮台,去河邊找鬼乏屯。 笑死根时,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辰晕。 我是一名探鬼主播蛤迎,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼含友!你這毒婦竟也來了替裆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤窘问,失蹤者是張志新(化名)和其女友劉穎辆童,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體南缓,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡胸遇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了汉形。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纸镊。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖概疆,靈堂內(nèi)的尸體忽然破棺而出逗威,到底是詐尸還是另有隱情,我是刑警寧澤岔冀,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布凯旭,位于F島的核電站,受9級特大地震影響使套,放射性物質(zhì)發(fā)生泄漏罐呼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一侦高、第九天 我趴在偏房一處隱蔽的房頂上張望嫉柴。 院中可真熱鬧,春花似錦奉呛、人聲如沸计螺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽登馒。三九已至,卻和暖如春咆槽,著一層夾襖步出監(jiān)牢的瞬間陈轿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留济欢,地道東北人赠堵。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓小渊,卻偏偏與公主長得像法褥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酬屉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

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

  • 前言 在android當(dāng)中對于UI體系當(dāng)中往往我們會在繪制UI的時候碰到各種各樣的問題而不知道從何解決半等, ...
    KerwinBarry閱讀 12,442評論 6 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評論 25 707
  • 友情 我希望的是不加雜念的 。 分享一段關(guān)于我的故事呐萨,是關(guān)于友情的杀饵。 友情本來應(yīng)該是單純不加雜念的,是美好的谬擦。不...
    夢里知十八閱讀 162評論 0 0
  • 做一件事切距,跟愛一個人一樣,首先要學(xué)會“毫無保留”惨远。有退路的人谜悟,遇到阻礙,永遠想回頭北秽;不給自己留退路的人...
    流浪貝貝閱讀 273評論 0 1
  • 文 | 晨光花開 我有一個優(yōu)秀的朋友葡幸。 作為一個習(xí)慣性只看朋友圈,不點贊贺氓,不發(fā)圖的蔚叨,三無潛水人士。 總是喜歡為TA...
    晨光花開閱讀 190評論 0 3