最近新作的项目上线,出现了一个让人抓狂的问题。在此记录一下!

现在的项目中,制作了一个界面非常复杂。整个结构是最外层一个Layout,封装了Menu键吊起的菜单,整个内容使用一个FrameLayout装载,这个layout中会有三个V4 Fragment。一个主Fragment和两个弹出的Fragment。主Fragment中分上中下结构,上部分展示图片,中部展示信息,下部分是一个可滑动的带4个Tab的ViewPager,这个ViewPager包在一个TabHost里面。整个嵌套的结构由于各种原因,达到了15层,并且在最里面的ViewPager中有两个View里面带了ListView,Item已经用RelativeLayout打平为一层。

这样一个布局,在3.0以上的手机上都表现良好问题!但是在2.x的手机上会出现

Android 2.3 I'm getting a StackOverflowError when the layout is drawn:

at android.view.View.draw(View.java:6880)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
       at android.view.View.draw(View.java:6883)
      at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
      ...

栈溢出问题。各种谷歌之后发现,很多人在2.x上也会有这个问题,究其原因就是View的层次嵌套过多,而2.x上Android给UI主线程分配了大概8KB的栈空间。大概最多只会有60到80层的stack frame。这个空间存储不了我的这个布局,后分析发现,由于最里层嵌套了Listview ,每个Item都有很深,而且每个Item在不断的进行着重绘。最终导致了2.x机型的栈溢出问题。

大部分的方法就是优化布局,减少嵌套。

和网上说的一样,接下来就是不断的优化,能减极简。但是到最后优化到评论的listview的层次大概为16层,在部分的android 2.x上依旧报这个问题。如果要继续优化下去,就得去掉fragment。因为在观看布局时发现,v4包的fragment会在最外层添加一个NosavestateFramelayout。而我用到的是Fragment中嵌套了Fragment,这就导致平白无故多了两层。如果要保持我现在的布局就得考虑去掉Fragment,全部改用View。但是项目紧张,根本来不及切换过来。于是只能进行降级。

当然还有一些比较不太优雅的解决方式:

比如在你最深层次容易爆崩溃的View中,把所有的View都重写Draw方法

privateHandler mHandler =newHandler();

@Overridepublicvoid draw(Canvas canvas){try{super.draw(canvas);}catch(StackOverflowError e){
mHandler.postDelayed(newRunnable(){publicvoid run(){
invalidate();}},1);}}

虽然最好的方法仍然是去优化你的布局,解嵌套,不仅能加快页面渲染速度,还能解决此问题。但是实在是没有任何可优化的时候,只能先使用这种比较脏的方式。我最后使用的是进行了降级,因为项目紧张,而且不容有失,所以降级成了最保险的选择。对于2.x系统这种强加的限制,表示真的是太蛋疼了!

The stack size of UI thread in Android 2.x is 12KB and in Android 4.x is 16KB. These 4KB make all the difference - since the above layout crashes on 2.x with StackOverflow.

对于嵌套过深的地方,尤其当有listview时,一定要注意,能去fragment就去掉fragment!尽量直接换用ViewGroup

记录:Android中StackOverflow的问题的更多相关文章

  1. Android中StackOverflow的问题

    最近出现了一个让人抓狂的问题. 现在的项目中,制作了一个界面非常复杂.Fragment中嵌套下拉刷新的Listview 这样一个布局,在3.0以上的手机上都表现良好问题!但是在2.x的比较弱爆的手机上 ...

  2. 在android中配置 slf4j + log4j 日志记录框架

    需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j ...

  3. Android学习记录(6)—将java中的多线程下载移植到Android中(即多线程下载在Android中的使用)③

    在这一节中,我们就来讲多线程下载以及断点续传在android中怎么使用,前两节是为本节做准备的,没有看前两节的同学,最好看完前面的两篇文章再来看这篇.其实在android端的应用和java基本上是差不 ...

  4. Android学习记录(3)—Android中ContentProvider的基本原理学习总结

    一.ContentProvider简介        当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据 ...

  5. Android学习记录(2)—Android中数据库的常见操作

    android中数据库操作是非常常见了,我们会经常用到,操作的方法也有很多种形式,这里我就把最常见的两种形式记录下来了,以备以后用到方便查看.我就不写注释和解释了,因为android数据库的操作和其它 ...

  6. Android中的路径记录

    Android中的路径记录 | RobinBlog 导航 导航 博客 分类 标签 友链 关于 搜索 Environment.getDataDirectory().getPath()=/dataEnvi ...

  7. Android学习记录(1)—Android中XML文件的序列化生成与解析

    xml文件是非常常用的,在android中json和xml是非常常用的两种封装数据的形式,从服务器中获取数据也经常是这两种形式的,所以学会生成和解析xml和json是非常有用的,json相对来说是比较 ...

  8. HTTPS 原理浅析及其在 Android 中的使用

    作者:曹丰斌   本文首先分析HTTP协议在安全性上的不足,进而阐述HTTPS实现安全通信的关键技术点和原理.然后通过抓包分析HTTPS协议的握手以及通信过程.最后总结一下自己在开发过程中遇到的HTT ...

  9. Kotlin 第二弹:Android 中 PDF 创建与渲染实践

    这是 Kotlin 练习的的第二篇.这一篇的由来是因为刚刚在 Android 开发者官网查看 API 的时候,偶然看到了角落里面的 pdf 相关. 我仔细看看了详细文档,发现这个还蛮有意思的,关键是编 ...

随机推荐

  1. 【转载】性能监视器(SSAS)

    使用性能监视器,您可以通过性能计数器监视 Microsoft SQL Server Analysis Services (SSAS) 实例的性能. 性能监视器是用于跟踪资源使用情况的 Microsof ...

  2. 学习hibernate,这个系列很不错

    从这里入,感谢作者啊. 看了很多资料,这个是最能让我入门的.感觉. http://blog.csdn.net/yerenyuan_pku/article/details/52745486

  3. 2017 ACM-ICPC Asia Xi'an Problem A XOR(异或线性基 )

    题目链接  2017西安赛区 Problem A 题意  给定一个数列,和$q$个询问,每个询问中我们可以在区间$[L, R]$中选出一些数. 假设我们选出来的这个数列为$A[i_{1}]$, $A[ ...

  4. response.getWriter().write()与out.print()的区别(转)

    1.首先介绍write()和print()方法的区别: (1).write():仅支持输出字符类型数据,字符.字符数组.字符串等 (2).print():可以将各种类型(包括Object)的数据通过默 ...

  5. C语言基础之变量、作用域

    1.变量的定义 变量类型 变量名; int score; 2.变量的赋值 score = 100; score = a; score = b = 100; 3.变量的输出 int a = 200; p ...

  6. 在VisualStudio 工具箱中隐藏用户控件

    当我们创建一个用户控件后,VisualStudio会自动将其添加到工具箱中,本来这是一个比较贴心的设计.但是,有的时候,我们并不想将用户控件放到工具箱中. 例如:在WPF中,为了避免一个页面的控件过多 ...

  7. PHP安全相关的配置

    PHP作为一门强大的脚本语言被越来越多的web应用程序采用,不规范的PHP安全配置可能会带来敏感信息泄漏.SQL注射.远程包含等问题,规范的安全配置可保障最基本的安全环境.下面我们分析几个会引发安全问 ...

  8. DTU

    DTU 编辑 DTU (Data Transfer unit),是专门用于将串口数据转换为IP数据或将IP数据转换为串口数据通过无线通信网络进行传送的无线终端设备.DTU广泛应用于气象.水文水利.地质 ...

  9. JavaScript入门:006—JS函数的定义

    JS函数的声明. 声明函数的格式例如以下: function 函数名(參数列表){ //函数语句: return 返回值; } 来看详细的函数声明.1.普通函数 <script type=&qu ...

  10. 使用JProfiler分析定位java内存泄露memory leak

    使用jprofiler远程profile JBoss应用服务器 项目中发现JBoss出现内存泄露, 从2G一直涨到3.5G左右 开始考虑使用jmap dump出内存来, 在用jhap打开浏览器分析. ...