編輯:關於Android編程
用的太多了,但是不知道原理。Xutils裡面捨棄了findViewById改用注解,當時也很不理解。一步步了解後,發現,相比注解的方式加載控件,findViewById的效率是很低的。注解+反射加載實例的過程看上去效率更高。
從activity的onCreate()裡開始:
點進去看源碼進入Activity.class類裡的方法:
Activity.class
發現這個返回的是getWindow()的findViewById方法,這個getWindow()是什麼?
Activity.class
返回的是一個Window對象,Window是個抽象類,包含的抽象方法可以管理Activity的UI組件,先這麼理解,這次主要理解findViewById的原理。
既然Activity的findViewById,是調用getWindow()(即Window對象)的findViewById方法,進入Window查找它的findViewById。
Window.class
返回的是getDecorView()的findViewById,前面說Window是個抽象類,不能具體實現管理ActivityUI組件的方法,那麼這個getDecorView()就是返回的是一個具體的View對象,來管理Activity的UI組件。
這個getDecorView是個抽象類,實現這個類,返回的View可以用來管理UI視圖。
然後Activity的findViewById方法,又通過getDecorView()(返回View)一步一步傳入到View的findViewById了。下面是View類。
View.class
邏輯很簡單了,直接調用findViewTraversal(),用mID跟傳入的id對比,如果存在就返回當前view,不存在就返回null。findViewTraversal從字面上理解,這個方法的意思是反復尋找view的ID。
到這裡我有點沒有頭緒了,憑感覺,查找mID應該是不斷+1比較,如果是ViewGroup,裡面還有View的話,還應該是一個遞歸的過程,從這裡看不出來。所以我看是找mID是如何設置的。
這是一個set方法,給子view控件添加ID,用來標識view。這個ID可以在R文件裡看到。
先把id給了mID,如果mID為空(就是沒有加ID呢),而且不是作為標簽(不太懂),那麼就給他加一個ID,動態生成控件的ID。
一個固定地址開始,一個一個找ID,設置的ID值似乎連續的。然後在後面的查找中,找遞歸,找循環。。沒有找到類似的代碼。
看上去,要知道mID才能知道答案。但是這樣分析下去得不到結果。
原因:
請看LinearLayout,RelativeLayout等等layout的繼承結構:
在ViewGroup中,已經對View的findViewTraversal()方法進行重寫了!
點進去找很快找到答案。
這個是重寫的方法:可以非常清楚的看到,findViewById的原理,是從頭開始找,遇到有子控件的,就遞歸接著找。先不考慮具體細節,到這裡,開始的猜想得到了證實。其中v.findViewById又調用View中的方法,而View的findViewById調用的findViewTraversal()。這樣實現了一個遞歸。
尊重作者注明出處:http://blog.csdn.net/bless2015/article/details/46618639
我在找findViewById的過程中,由於開始忽略子類ViewGroup對View方法的重寫,導致在View.class萬行代碼中陷入死循環,找不到想看到的方法。但是還是找到一些有趣的東西,有時間再整理下來。
任務描述有一套C寫的代號為“Shooter”的核心算法庫可以解決我們面臨的一些問題,只是這個庫一直用在其他平台。我們現在的任務是將其復用到Andr
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身
1、dex文件分析邏輯上,可以把dex文件分成3個區,頭文件、索引區和數據區。索引區的ids後綴為identifiers的縮寫。 headerdex文件裡的he
安卓手機重置便攜式熱點密碼方法如何?小編就來演示一下。 開啟手機,進入手機設置界面; 選擇“無線和網絡”; 選擇&