界面的展示部分:------->界面的加载(Activity、Window、View之间的关系)
我们知道在Instrumentation.java中有个newActivity(),通过反射创建了MainActivity对象,此时MainActivity对象并没有去调用其生命周期 的方法onCrteate( ),而是activity.attach(.....),
ok ,但这里我们先去看看我们熟悉的代码;
Activity中的生命周期方法onCreate(...)中调用了setContentView,如下
1 2 3 4 5 | @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); this .setContentView(R.layout.xxxx); } |
我们看一下setContentView(..........)这个方法的源码:
1 2 3 4 5 6 7 8 9 | public void setContentView( int layoutResID) { getWindow().setContentView(layoutResID); } public void setContentView(View view) { getWindow().setContentView(view); } public void setContentView(View view, ViewGroup.LayoutParams params) { getWindow().setContentView(view, params); } |
我用红色标记了,他们都在做一个动作---getWindow(),即往获得Window上设置布局(或view),那这个Window在什么时候创建的?
我们看一下activity.attach(.....)中的源码:
1 2 3 4 5 6 | final void attach(.......) { ... //创建一个Window对象 mWindow = PolicyManager.makeNewWindow( this ); .... } |
我们发现Window是个抽象类,那么这里它创建的是Window的哪一个子类?我们继续一步一步看源码:
PolicyManager.java中
1 2 3 4 5 6 | public final class PolicyManager { private static final IPolicy sPolicy; public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); } } |
接口IPolicy的实现类Policy.java
1 2 3 | public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); } |
我们知道了是创建了一个PhoneWindow.
--------------------------------------------
现在我们重新回到MainActivity对象刚被new出来时,调用了attach(...)方法,其实是创建了一个PhoneWindow对象,
然后再去调用onCreate()方法,去设置布局我们从上面的源码我们看到,
其实setContentView()目的就是为了调用PhoneWindow的setContentView(...),看一下源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | public class PhoneWindow extends Window implements MenuBuilder.Callback { private DecorView mDecor; private ViewGroup mContentParent; private LayoutInflater mLayoutInflater; //DecorView其实就是Window中View的RootView private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { } @Override public void setContentView( int layoutResID) { if (mContentParent == null ) { //没看懂,可以理解为让mDecor和mContentParent产生了关系 //其实就是把View放在RootView上 installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null ) { cb.onContentChanged(); } } private void installDecor() { if (mDecor == null ) { mDecor = generateDecor(); mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); mDecor.setIsRootNamespace( true ); } if (mContentParent == null ) { mContentParent = generateLayout(mDecor); ..... .... } } } |
到此结合上面的XML图 我们明白了界面是如何展现出的.