Android开发中StackOverflowError错误实例分析

一、概述

我在一个复杂的layout嵌套较多的android界面,碰到了java.lang.StackOverflowError这个Fatal Exception,app程序crash退出。这个错误出现的比较奇怪,在我做技术调研的时候,这个界面是放在单独的一个程序中展示的,工作很正常,没有出现这个严重错误,当将其嵌入到一个ActivityGroup后才报错。



       android SDK中对该错误的出现的场景描述为:由于栈调用的层次太多,超过了虚拟器dalvik的最大限制(作为一个虚拟器参数,可定制)导致的。当程序编写错误导致无限递归调用时会触发,此外程序正确但是递归调用的层次过深也会触发。



       结合我的界面的情况,在单独程序中运行时没有问题,则说明不存在死循环的无限递归错误。观察该界面的集成情况,发现为了Tab页实现,该界面在显示时,被两个ActivityGroup嵌套,增加了6层显式父layout。而因为该界面复杂,设计时,list_header view的layout深度为5层,而list_item的深度则为6层。原因定位为界面嵌套层次过深。

二、解决方法
         解决嵌套过深的基本思路是在实现同样的效果的前提下减少界面的layout深度。在我将list_header view layout深度由5层精简为3层,list_item 深度由6层减少为4层后,该错误被解决。具体的方法有:
1)       多用RelativeLayout的各种布局属性来完成布局,而避免过多使用嵌套layout来实现。
2)       占位或填充剩余空间的元素多用View,避免使用layout等viewGroup。



总结下,从实际的数据来看,设计中layout嵌套深度超过10层,就应该考虑下优化了,否则就会出现java.lang.StackOverflowError的crash了。
三、错误详细日志
E/AndroidRuntime( 5196): FATAL EXCEPTION: main
E/AndroidRuntime( 5196): java.lang.StackOverflowError
E/AndroidRuntime( 5196):    at android.graphics.Paint.measureText(Paint.java:1057)
E/AndroidRuntime( 5196):    at android.text.Styled.drawDirectionalRun(Styled.java:267)
E/AndroidRuntime( 5196):    at android.text.Styled.measureText(Styled.java:430)
E/AndroidRuntime( 5196):    at android.text.Layout.measureText(Layout.java:1655)
E/AndroidRuntime( 5196):    at android.text.Layout.getLineMax(Layout.java:689)
E/AndroidRuntime( 5196):    at android.text.Layout.draw(Layout.java:340)
E/AndroidRuntime( 5196):    at android.widget.TextView.onDraw(TextView.java:4050)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6740)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.view.View.buildDrawingCache(View.java:6502)
E/AndroidRuntime( 5196):    at android.view.View.getDrawingCache(View.java:6288)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1565)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.widget.AbsListView.dispatchDraw(AbsListView.java:1365)
E/AndroidRuntime( 5196):    at android.widget.ListView.dispatchDraw(ListView.java:3046)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6846)
E/AndroidRuntime( 5196):    at android.widget.AbsListView.draw(AbsListView.java:2257)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime( 5196):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime( 5196):    at android.view.View.draw(View.java:6743)
E/AndroidRuntime( 5196):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime( 5196):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842)
E/AndroidRuntime( 5196):    at android.view.ViewRoot.draw(ViewRoot.java:1407)
E/AndroidRuntime( 5196):    at
W/ActivityManager(   71):   Force finishing activity com.baidu.test/.CloudDemActivity
W/WindowManager(   71): No window to dispatch pointer action 1

Android开发中StackOverflowError的更多相关文章

  1. Android学习探索之Java 8 在Android 开发中的应用

    前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...

  2. android开发中fragment获取context

    在用到fragment时无法使用.this来指定当前context内容,android开发中fragment获取context,可以使用getActivity().getApplicationCont ...

  3. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  4. Android开发中的输入合法性检验

    Why ? 合法性检查对于程序的健壮性具有重要作用.在Android开发中,良好的合法性检查设计机制可以使程序更加清晰,产生bug更少,交互更加友好. What ? 合法性检查的目的在于确定边界.对于 ...

  5. 在android开发中使用multdex的方法-IT蓝豹为你整理

    Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...

  6. 怎样实现了捕获应用中的日志在android开发中

    怎样实现了捕获应用中的日志在android开发中,大家可研究一下. Process mLogcatProc = null; BufferedReader reader = null; try { mL ...

  7. Android开发中Eclispe相关问题及相应解决(持续更新)

    1.Eclipse项目中的Android Private Libraries没有自动生成. 一般而言,在Android开发中,项目中引用到的jar包会放到项目目录中的libs中,引入库会放到Andro ...

  8. Android开发中的问题及相应解决(持续更新)

    最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...

  9. 关于Android开发中的证书和密钥等问题

    关于Android开发中的证书和密钥等问题 引言 除了Android发布应用签名时需要用到证书外,在进行google Map Api开发和Facebook SDK API开发等时都需要申请API Ke ...

随机推荐

  1. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  2. VB.NET 泛型类型的应用经验

    VB.NET编程语言中的数据类型种类繁多,初学者要想全部掌握这些类型的应用是一个比较困难的步骤.今天我们先让大家了解一下VB.NET泛型类型这一高阶技术的应用,以便让大家对这一语言进行深入的解读. 定 ...

  3. mycat 1.6 简单的操作实例

    环境: centos7.4 + mysql5.7.20 + mycat1.6单台主机上安装了5台mysql_5.7.20 实例(3306,3307,3308,3309,3310)3306为独立实例 ( ...

  4. Scrapy框架

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...

  5. Linux查看CPU、内存、进程使用情况(转)

    在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 top 命令后,CPU 使用状态会 ...

  6. Linux学习之CentOS(十七)-----释放 Linux 系统预留的硬盘空间 与Linux磁盘空间被未知资源耗尽 (转)

    释放 Linux 系统预留的硬盘空间  大多数文件系统都会保留一部分空间留作紧急情况时用(比如硬盘空间满了),这样能保证有些关键应用(比如数据库)在硬盘满的时候有点余地,不致于马上就 crash,给监 ...

  7. Go 处理yaml类型的配置文件

    先说一下,这里用到了很多关于反射类型的功能,可能刚开始看代码,如果对反射不熟悉的可能会不是非常清晰,但是同时也是为了更好的理解golang中的反射,同时如果后面想在代码中可以直接从我的git地址get ...

  8. 蚂蚁代理免费代理ip爬取(端口图片显示+token检查)

    分析 蚂蚁代理的列表页大致是这样的: 端口字段使用了图片显示,并且在图片上还有各种干扰线,保存一个图片到本地用画图打开观察一下: 仔细观察蓝色的线其实是在黑色的数字下面的,其它的干扰线也是,所以这幅图 ...

  9. 【kmp】 剪花布条 HDU - 2087

    [题意概述] [解题思路] 从左往右找,看有几个匹配的字符串,但要注意例如 aaaaaa  aa的输出是3 而不是5,可以这样理解:画布需要减去,一旦减去也就没有了的 [AC] #include< ...

  10. Docker如何获取镜像

    可以使用 docker pull 命令来从仓库获取所需要的镜像. 下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像. $ sudo docker pull ...