转载请注明出处:http://blog.csdn.net/crazy1235/article/details/51471280
这个函数是在常见不过的了!
setContentView(R.layout.activity_test_view);
但是调用了这个函数设置Activity布局的时候,android系统究竟做了什么操作呢?
往下看!
setContentView()
我们新建项目模式都是使用的 Theme.AppCompat 主题,Activity都是继承于 AppCompatActivity 的!
OK,下面来一步步跟踪源码!
在AppCompatActivity中:
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
调用的是 getDelegate() 中对应的 setContentView() 函数。
@NonNull
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
AppCompatDelegate 及其子类
AppCompatDelegate 是 AppCompat代理类!
调用AppCompatDelegate中的静态方法create() :
public static AppCompatDelegate create(Activity activity, AppCompatCallback callback) {
return create(activity, activity.getWindow(), callback);
}
接着又调用了另外一个重载的静态函数!
private static AppCompatDelegate create(Context context, Window window,
AppCompatCallback callback) {
final int sdk = Build.VERSION.SDK_INT;
if (BuildCompat.isAtLeastN()) {
return new AppCompatDelegateImplN(context, window, callback);
} else if (sdk >= 23) {
return new AppCompatDelegateImplV23(context, window, callback);
} else if (sdk >= 14) {
return new AppCompatDelegateImplV14(context, window, callback);
} else if (sdk >= 11) {
return new AppCompatDelegateImplV11(context, window, callback);
} else {
return new AppCompatDelegateImplV9(context, window, callback);
}
}
在这个函数里根据系统版本来创建不同的代理实现类!
通过查看这几个类的源码可以发现它们之间的继承关系如下图:
可以看出,setContentView() 方法实现是在 AppCompatDelegateImplV9 这个类中!
@Override
public void setContentView(View v) {
ensureSubDecor(); //
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
contentParent.addView(v);
mOriginalWindowCallback.onContentChanged();
}
@Override
public void setContentView(int resId) {
ensureSubDecor(); //
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mOriginalWindowCallback.onContentChanged();
}
@Override
public void setContentView(View v, ViewGroup.LayoutParams lp) {
ensureSubDecor(); //
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
contentParent.addView(v, lp);
mOriginalWindowCallback.onContentChanged();
}
我们平时在Activity中主要用到的就是 public void setContentView(int resId) 这个函数!就那这个来说!
ensureSubDecor()
三个重载函数内部都是首先调用了 ensureSubDecor() 这个函数!
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
mSubDecor = createSubDecor(); // !!!
// If a title was set before we installed the decor, propagate it now
CharSequence title = getTitle();
if (!TextUtils.isEmpty(title)) {
onTitleChanged(title);
}
applyFixedSizeWindow();
onSubDecorInstalled(mSubDecor);
mSubDecorInstalled = true;
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
if (!isDestroyed() && (st == null || st.menu == null)) {
invalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR);
}
}
}
mSubDecorInstalled 默认是false,所以初次会调用 createSubDecor() 来创建 mSubDecor,实际上它就是一个ViewGroup!
private ViewGroup createSubDecor() {