Android从xml加载到View对象过程解析

2019-12-10 18:49:51于海丽
易采站长站为您分析 Android从xml加载到View对象过程解析的相关资料,需要的朋友可以参考下  

我们从Activity的setContentView()入手,开始源码解析,

//Activity.setContentView
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initActionBar();
}
//PhoneWindow.setContentView
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}

发现是使用mLayoutInflater创建View的,所以我们去LayoutInflater.inflate()里面看下,

public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
if (DEBUG) System.out.println("INFLATING from resource: " + resource);
XmlResourceParser parser = getContext().getResources().getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}

先根据resource id 获取到XmlResourceParseer,意如其名,就是xml的解析器,继续往下,进入到inflate的核心方法,有些长,我们只分析关键部分:

public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
......
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("<merge /> can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs, false);
} else {
// Temp is the root view that was found in the xml
View temp;
if (TAG_1995.equals(name)) {
temp = new BlinkLayout(mContext, attrs);
} else {
temp = createViewFromTag(root, name, attrs);
}
......
} catch (XmlPullParserException e) {
InflateException ex = new InflateException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
InflateException ex = new InflateException(
parser.getPositionDescription()
+ ": " + e.getMessage());
ex.initCause(e);
throw ex;
} finally {
// Don't retain static reference on context.
mConstructorArgs[0] = lastContext;
mConstructorArgs[1] = null;
}
return result;
}
}