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

现在的项目中,制作了一个界面非常复杂。整个结构是最外层一个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. ios控件渐变色的处理

    +(CAGradientLayer *)gradientColorWithBounds:(CGRect)bounds startColorHexString:(NSString *)startColo ...

  2. (sql server)玩转-数据库行列转换

    虽然开发过程中没用过行列转换,但是听说面试时常常会遇到这个问题,以前在网上也看到过大神的例子,今天自己仔细的玩了下,希望和大家分享一下了. 注意:列转行的方法可能是我独创的了,呵呵,因为在网上找不到哦 ...

  3. POJ 2337 Catenyms (欧拉图)

    本文链接http://i.cnblogs.com/EditPosts.aspx?postid=5402042 题意: 给你N个单词,让你把这些单词排成一个序列,使得每个单词的第一个字母和上一个字单词的 ...

  4. superviosrd进程管理

    supervisor进程管理器---------------------------1. 安装依赖yum install python-setuptools-devel 2. 安装supervisor ...

  5. NOI2014 部分题解

    感觉NOI2014的一些题目也是比较好做的... 但是笔者往往有思路却没有想清楚就开始搞了...这样还是不太好.. Day1 T1 起床困难综合征  (我感觉这题应该叫综合征不是综合症...)   a ...

  6. 全面理解java自动装箱和拆箱(转)

    自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接. 如 ...

  7. 解决413 Request Entity Too Large

    修改nginx配置    这是最简单的一个做法,着报错原因是nginx不允许上传配置过大的文件,那么件把nginx的上传大小配置调高就好. 1.打开nginx主配置文件nginx.conf,一般在/u ...

  8. [ZZ]机器学习的入门

    转载自: http://www.cnblogs.com/mq0036/p/7131678.html 本篇虽不是这一个月的流水账,但是基本按照下面的思路对着一个月做了一次总结: 什么是机器学习? 机器学 ...

  9. hdu1008(c++)

    分清上升停留下降一步步来就是了 #include<iostream>#include<vector>using namespace std;int main(){ int N, ...

  10. docker运行mysql

    http://blog.csdn.net/u011492260/article/details/77970445 第一步: 安装Docker:首先到docker官网下载适合自己电脑当前系统的版本,并安 ...