首页 > 代码库 > Android系统启动-->应用启动-->界面的展示(三)

Android系统启动-->应用启动-->界面的展示(三)

界面的展示部分:------->界面的加载(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图 我们明白了界面是如何展现出的.
















Android系统启动-->应用启动-->界面的展示(三)