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. 51Nod 1331 狭窄的通道

    有一个长为L的狭窄通道,我们假设这个通道在x轴上,其两个出口分别在x=0与x=L处.在这个通道里有N只狼,第i只狼有一个初始位置ai,它想到达位置bi(0<=i=L处空间足够大可以装下任意数量的 ...

  2. SPOJ DQUERY树状数组离线or主席树

    D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status ...

  3. Mysql锁机制--概念、分类及基础命令

    Mysql 系列文章主页 =============== 1 概念 在 Java 程序中,当多线程并发访问某个资源的时候,如果有非线程安全的操作,那么需要通过加锁来保护之.同理,在 Mysql 中,如 ...

  4. redis锁处理并发问题

    redis锁处理并发问题 redis锁处理高并发问题十分常见,使用的时候常见有几种错误,和对应的解决办法. set方式 setnx方式 setnx+getset方式 set方式 加锁:redis中se ...

  5. FreeMarker学习教程

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  6. canvas初学 半动态画太极图

    可直接复制粘贴运行 <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head&g ...

  7. C# 虹软SDK视频人脸识别和注册

    一,准备工作 1.Afoge视频参数类 using AForge.Video.DirectShow; using System; using System.Collections.Generic; u ...

  8. Mysql数据库连接报错!1130:host XXX is not allowed to connect to this mysql server

    我猜想是可能是连接的用户权限问题.结果这样子操作mysql库,可以解决此问题.在本机登入mysql后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost” ...

  9. JAVA中接口的使用

    抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,那么就是接口(interface)了.什么是接口,简单的讲,接口就是抽象类的进一步抽象,这种进一步的抽象只定义了一种规范,而不需要关心具体 ...

  10. Spring统一返回Json工具类,带分页信息

    前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...