界面的展示部分:------->界面的加载(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图 我们明白了界面是如何展现出的.
时间: 2024-12-28 21:45:20