Android 布局优化 java.lang.StackOverflowError

本文介绍了解决Android应用因布局层级过多导致的堆栈溢出问题的方法。通过使用HierarchyViewer工具分析布局层级,利用<include/>和<merge/>标签优化布局,最终解决了HTC某型号手机上的崩溃问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         最近做的一个安卓项目,由于层级复杂导致层级嵌套过多,结果在htc上的一款机器上长按文档框崩溃,报堆栈溢出异常,  java.lang.StackOverflowError
      android SDK中对该错误的出现的场景描述为:由于栈调用的层次太多,超过了虚拟器dalvik的最大限制(作为一个虚拟器参数,可定制)导致的。当程序编写错误导致无限递归调用时会触发,此外程序正确但是递归调用的层次过深也会触发。网上查找资料发现安卓布局层级过多也会导致这个异常。在 Android SDK 中包含了一个Heirachy Viewer 工具,在sdk tool 文件中,使用该工具可以在您的程序运行的时候分析程序的布局。使用该工具来发现布局中的瓶颈所在。Hierarchy Viewer 让你选择其连接的设备或者模拟器中的一个运行中的程序,然后显示该界面的布局树形结构。在每个控件方块中的交通灯分别代表 计算尺寸(Measure)、布局子控件(Layout)、和绘制的性能,通过颜色来帮助您分析潜在的问题。 使用这个工具可以很清晰的看到当前页面的层级结构,发现我的Edittext  处于10级以上,层级太深,尝试着优化布局。

    1、使用<include /> 标签来重用layout代码,如果在一个项目中需要用到相同的布局设计,可以通过<include /> 标签来重用layout代码
     2、使用<merge /> 标签来减少视图层级结构,merge也有一些使用限制: 只能用于xml layout文件的根元素;在代码中inflate一个以merge为根元素的布局文件时候,你需要指定一个ViewGroup 作为其容器,并且要设置attachToRoot 为true
       最终使用merge标签,替换掉include中的根节点,解决上面的问题。

 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:883) at android.widget.LinearLayout.onMeasure(LinearLayout.java:726) at android.view.View.measure(View.java:29007) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132) at com.android.internal.policy.DecorView.measureChildWithMargins(DecorView.java:3010) at android.widget.FrameLayout.onMeasure(FrameLayout.java:205) at com.android.internal.policy.DecorView.onMeasure(DecorView.java:911) at android.view.View.measure(View.java:29007) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:5801) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3999) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4393) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3667) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:12113) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2459) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doFrame(Choreographer.java:1448) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9913) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)
最新发布
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值