XML布局嵌套多少层会导致OOM
程序员文章站
2022-06-16 10:10:04
查看setContentView源码可以看到,最终调用的是rInflate。首先遍历所有的节点,假如是普通的view就直接获取,是Viewgroup的话会调用rInflateChildren,发现在rInflateChildren里面调用的还是rInflate,是一个递归调用。而且没有退出条件,就会导致不断地进行压栈。类似这种情况,JVM 实际会抛出 *Error;当然,如果 JVM 试图去扩展栈空间的的时候失败,则会抛出 OutOfMemoryError。栈最多存放多少栈帧...
查看setContentView源码可以看到,最终调用的是rInflate。
首先遍历所有的节点,假如是普通的view就直接获取,是Viewgroup的话会调用rInflateChildren,
发现在rInflateChildren里面调用的还是rInflate,是一个递归调用。
而且没有退出条件,就会导致不断地进行压栈。类似这种情况,JVM 实际会抛出 *Error;当然,如果 JVM 试图去扩展栈空间的的时候失败,则会抛出 OutOfMemoryError。
栈最多存放多少栈帧取决于虚拟机设置的参数。
/**
* Recursive method used to inflate internal (non-root) children. This
* method calls through to {@link #rInflate} using the parent context as
* the inflation context.
* <strong>Note:</strong> Default visibility so the BridgeInflater can
* call it.
*/
final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException {
rInflate(parser, parent, parent.getContext(), attrs, finishInflate);
}
/**
* Recursive method used to descend down the xml hierarchy and instantiate
* views, instantiate their children, and then call onFinishInflate().
* <p>
* <strong>Note:</strong> Default visibility so the BridgeInflater can
* override it.
*/
void rInflate(XmlPullParser parser, View parent, Context context,
AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
final int depth = parser.getDepth();
int type;
boolean pendingRequestFocus = false;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String name = parser.getName();
if (TAG_REQUEST_FOCUS.equals(name)) {
pendingRequestFocus = true;
consumeChildElements(parser);
} else if (TAG_TAG.equals(name)) {
parseViewTag(parser, parent, attrs);
} else if (TAG_INCLUDE.equals(name)) {
if (parser.getDepth() == 0) {
throw new InflateException("<include /> cannot be the root element");
}
parseInclude(parser, context, parent, attrs);
} else if (TAG_MERGE.equals(name)) {
throw new InflateException("<merge /> must be the root element");
} else {
final View view = createViewFromTag(parent, name, context, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
rInflateChildren(parser, view, attrs, true);
viewGroup.addView(view, params);
}
}
if (pendingRequestFocus) {
parent.restoreDefaultFocus();
}
if (finishInflate) {
parent.onFinishInflate();
}
}
本文地址:https://blog.csdn.net/weixin_37165769/article/details/110958199