JAVA获取XML有层数_XML布局嵌套多少层会导致OOM

在解析XML布局时,由于rInflate方法的递归调用,没有明确的退出条件,可能导致无限递归并消耗大量栈空间。当栈帧超过JVM设定的最大值时,会抛出StackOverFlowError。如果JVM尝试扩展栈空间失败,将抛出OutOfMemoryError。此问题通常发生在深度嵌套的XML布局中。
摘要由CSDN通过智能技术生成

查看setContentView源码可以看到,最终调用的是rInflate。

首先遍历所有的节点,假如是普通的view就直接获取,是Viewgroup的话会调用rInflateChildren,

发现在rInflateChildren里面调用的还是rInflate,是一个递归调用。

而且没有退出条件,就会导致不断地进行压栈。类似这种情况,JVM 实际会抛出 StackOverFlowError;当然,如果 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.

* Note: 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().

*

* Note: 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(" cannot be the root element");

}

parseInclude(parser, context, parent, attrs);

} else if (TAG_MERGE.equals(name)) {

throw new InflateException(" 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();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值