編輯:關於android開發
一、概述
Activity 可以說是應用程序的載體(也可以理解為界面的載體,但是不界面),用戶能夠在上面繪制界面(Activity本身不繪制界面),並提供用戶處理事件的API,維護應用程序的生命周期(Android應用程序是由多個 Activity 堆積而成,而各個 Activity 又有其獨立的生命周期)。
Activity內部組合了一個Window(這是一個抽象類,具體是PhoneWindow)對象。我們自己寫的擴展一個Activity時,在onCreate 方法中調用 setContentView,實際上是調用Window對象的 setContentView,所以說界面繪制全部是由Window類的實現類(PhoneWindow類)來完成的。 二、源碼分析 1. 跟蹤源碼進入到 Activity 中看到 setContentView的實現如下:1 public void setContentView(int layoutResID) { 2 getWindow().setContentView(layoutResID); 3 initActionBar(); 4 }
看第二行代碼,先得到一個 Window 對象。
1 public Window getWindow() { 2 return mWindow; 3 }
getWindow 很簡單只是返回一個 對象而已,那麼,Window對象到底是在哪兒實例化的呢?
我們可以看看,Activity 中的 attach 方法,這裡面得到了一個 Window 對象
mWindow = PolicyManager.makeNewWindow(this);
2. 由Activity中的 setContentView 方法可以看到,界面繪制並不是由 Activity 完成的,他是調用了 Window 類的 setContentView 來實現的。所以我們就去看看 Window 類的代碼:
public abstract void setContentView(int layoutResID);
我們可以看到, Window 類是一個抽象類,並且 setContentView 是一個抽象方法。所以說,其具體實現是由 實現 Window類的類來完成的(PhoneWindow)。
3. 在文檔中已經描述了:The only existing implementation of this abstract class is android.policy.PhoneWindow. 我們要來看看這個類才能知道 界面是如何完成繪制的。
1 @Override 2 public void addContentView(View view, ViewGroup.LayoutParams params) { 3 if (mContentParent == null) { 4 installDecor(); 5 } 6 if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { 7 // TODO Augment the scenes/transitions API to support this. 8 Log.v(TAG, "addContentView does not support content transitions"); 9 } 10 mContentParent.addView(view, params); 11 final Callback cb = getCallback(); 12 if (cb != null && !isDestroyed()) { 13 cb.onContentChanged(); 14 } 15 }
先判斷mContentParent是否為空,如果為空就調用 installDecor 方法(自己可以看一下源碼), 最後會添加 View。
Window 中有一個 DecorView,可以理解為“ViewRoot”,引號是說其實這個“ViewRoot”是一個View或者說ViewGroup,是最初始的根視圖。構建視圖就是向這裡面添加。所以到這裡大概可以知道,installDecor 方法大概是 構建一個根視圖。
三、總結
Activity創建時系統會調用其 attach 方法,將其添加到ActivityThread當中,在attach方法中創建了一個window對象。
我們知道Window組合了一個 DocerView, 當用戶調用 setContentView 的時候會把一棵 View 樹仍給DocerView。 View樹是已經創建好的實例對象,所以我們要研究 DocerView是個什麼東西,它是如何被創建的。
我們回頭看看Window實現裡邊的setContentView方法,代碼中有一個 installDecor 方法,這個方法中有一個 generateDecor。 generateDecor直接new了一個DecorView對象
protected DecorView generateDecor() { return new DecorView(getContext(), -1); }
當 DocerView 被創建後,就會調用 mContentParent.addView(view, params); 來將 view 添加到 DocerView當中。
最後總結一下:
Activity在onCreate時調用attach方法,在attach方法中會創建window對象。window對象創建時並沒有創建 DocerView 對象。用戶在Activity中調用setContentView,然後調用window的setContentView,這時會檢查DecorView是否存在,如果不存在則創建DecorView對象,然後把用戶自己的 View 添加到 DecorView 中。
裝模作樣的聲明一下:本博文章若非特殊注明皆為原創,若需轉載請保留原文鏈接(http://www.cnblogs.com/kest/p/5141817.html)及作者信息k_est
5大移動應用加固平台評測,移動應用加固評測5大移動應用加固平台評測 前言:由於安卓APP是基於Java的,所以極容易被破解,一個不經過加固的APP猶如裸奔一
【Android】常見問題解答,android這裡匯總了用C#和VS2015開發Android App時一些常見的最基本的問題及解決辦法,以後有新的問題時都在這裡一並回答
Android添加圖片到ListView或者 RecyclerView顯示, 先上圖 點擊+號就去選擇圖片 實際上這個添加本身就是一個List
注冊界面設計及實現之(三)SharedPerferences實現數據暫存,sharedptr實現開發步驟: 創建一個SharedPerferences接口對象,並使用其