Android里那些令人費解的命名(一)ViewRoot

ViewRoot不是View

對於剛剛開始看Android源碼的同學來說,一般很少有像羅昇陽大神那樣,從底層開始看。90%的人應該是從最常見的視圖層開始看,從View到ViewGroup,再到ViewRoot、DecorView、PhoneWindow,理清ViewTree的概念。

這其中最容易讓人誤解或自以為是的部分,可能就是ViewRoot了,甚至很多面試者在問到ViewRoot是什麼的時候,很自然而然的會說,是一個ViewTree的根節點……然而實際上,ViewRoot,或者說它的實現類ViewRootImpl,跟View沒有任何關係。它不是View的子類或父類。對於結構而言,在大部分正常情況下,一顆ViewTree的根節點往往是DecorView,而DecorView的根則是PhoneWindow,跟ViewRoot真沒什麼關係。

Read The Fucking Code:

frameworks/base/core/java/android/view/WIndowManagerGolobal.java

public void addView(View view, ViewGroup.LayoutParams params,n Display display, Window parentWindow) {nn //...略...nn ViewRootImpl root;n View panelParentView = null;nn synchronized (mLock) {n // Start watching for system property changes.n //...略...n root = new ViewRootImpl(view.getContext(), display);nn view.setLayoutParams(wparams);nn mViews.add(view);n mRoots.add(root);n mParams.add(wparams);n }nn // do this last because it fires off messages to start doing thingsn try {n root.setView(view, wparams, panelParentView);n } catch (RuntimeException e) {n // BadTokenException or InvalidDisplayException, clean up.n synchronized (mLock) {n final int index = findViewLocked(view, false);n if (index >= 0) {n removeViewLocked(index, true);n }n }n throw e;n }n}n

從上面這段代碼可以看出,ViewRoot的實現類ViewRootImpl在Framework層的WindowManagerGlobal中初始化,其中包含了三個ArrayList(在舊版本中實現是數組),其中mViews代表DecorView,mRoots代表ViewRoot。

從這裡可以看出,對於應用層(相對底層而言)來說,ViewRoot實際上和DecorView沒有像ViewTree里父子節點那種包含關係。而後面的root.setView(view, wparams, panelParentView),更是證明了,DecorView的parentView也不是ViewRoot,而實際上是PhoneWindow。

有興趣的同學可以看一下ViewRoot的這段源碼,在frameworks/base/core/java/android/view/ViewRootImpl.java里,代碼流程非常繁雜,我不貼具體代碼了。它真正的作用是將DecorViewattach到PhoneWindow上.

所以,實際上ViewRoot的真正左右是作為一個DecorView的「管理者」,它本身**並不是一個視圖節點**,它更確切的應該叫做ViewTreeManager或許比較合理。它本質上是一個管理類,如果按照名字去理解的話,看ViewTree這部分源碼絕對能暈到吐血。

總結一下:

  • ViewRoot是一個ViewTree的管理者,而不是ViewTree的根節點。
  • 嚴格意義上說,ViewTree的根節點只有DecorView。
  • ViewRoot將DecorView和PhoneWindow「組合」起來。

後記

本來有蠻多東西想寫,結果光是想要把一個點講清就用了這麼多筆墨。果然」表達一個觀點「容易,而」證明一個觀點「的過程才是真正費工夫的,想要跟大部分人」講清楚「更是極度耗費腦力的活動。所以本來想寫的一篇文可能只有變成一篇連載形式的文了。

另外,上一篇寫Gradle Task的文,私下收到了很多反饋說,沒必要那麼麻煩,懂怎麼配置就行了……對於這種態度我其實蠻難理解的……比如像Gradle Task里講到的,教你怎麼用doLast,doFirst標籤的文章可能遍大街都是,但所謂的First和Last是相對什麼的?哪兒就First了,憑空冒出來瞎起名字的?不明白Task的Configuration State和Execution State兩種狀態,就解釋不清Task相對於什麼的First和Last……好奇心如何滿足?

當然,如果覺得我太過「啰嗦」,歡迎選擇性閱讀。

覺得有用還請隨意打賞一發~~

推薦閱讀:

Google 開發了很多優秀的 iOS 應用, Apple 卻沒有開發任何 Android 應用,這是為什麼,意味著什麼?
Eclipse中安卓虛擬機只有界面,沒有返回鍵什麼的,少了一半?
有哪些比較好的Android異常(crash、ANR、內存泄漏等等)處理機制?
Qt的前景如何?Qt for Android 好嗎?

TAG:Android开发 | Android系统源码 | Android |