咱们既然是要分析这三者的关系,首先我们应该要找到着手点。
这个点其实就在咱们最长用activity里开始入手,咱们都知道activity里有个方法setContentView方法。所以咱们就从这里开始入手吧~
### Activity.java
public void setContentView(View view) {
getWindow().setContentView(view);
}
getWindow对应的为Window对象,而window对象是一个抽象类,要找到window对象在哪里初始化的
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
......
mWindow = PolicyManager.makeNewWindow(this);
......
}
### PolicyManager.java
private static final IPolicy sPolicy;
public static Window makeNewWindow(Context context) {
return sPolicy.makeNewWindow(context);
}
### IPolicy.java
/* The implementation of this interface must be called Policy and contained
* within the com.android.internal.policy.impl package */
public interface IPolicy {
public Window makeNewWindow(Context context);
...
}
### Policy.java
public class Policy implements IPolicy {
...
public PhoneWindow makeNewWindow(Context context) {
return new PhoneWindow(context);
}
...
}
由此可知mWindow对象实在activity得attach方法中创建的
实际上setContentView方法是调用PhoneWindow得setContentView方法
### PhoneWindow.java
@Override
public void setContentView(View view) {
setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
会从一个参数的走到2个参数的
installDecor()方法
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
.......
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
.......
}
}
其中mDecor是一个DecorView对象,DecorView继承自FrameLayout
generateLayout(mDecor)方法
protected ViewGroup generateLayout(DecorView decor) {
......
if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
}
......
mDecor.startChanging();
View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
......
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
......
mDecor.finishChanging();
return contentParent;
}
通过上面方法拿到了mContentParent
再次回归setContentView
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
......
} else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
......
}
会判断mContentParent是否为空,如果为空说明第一次创建则移除mContentParent里面所有的view,然后再把咱们自己得view对象放进去
|
|