最近出现了一个让人抓狂的问题。

现在的项目中,制作了一个界面非常复杂。Fragment中嵌套下拉刷新的Listview

这样一个布局,在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方法

  private Handler mHandler =new Handler();

@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的问题

    最近新作的项目上线,出现了一个让人抓狂的问题.在此记录一下! 现在的项目中,制作了一个界面非常复杂.整个结构是最外层一个Layout,封装了Menu键吊起的菜单,整个内容使用一个FrameLayout ...

  2. 解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题

    解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题http ...

  3. Android中如何查看内存

    文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...

  4. Android中px和dip的区别

    在Android手机的诞生之初,由于Android系统是开源的,一开始便有众多的OEM厂商对Android手机进行深度定制,于是乎Android手机的皮肤和屏幕大小都变得百花齐放,这可苦逼了我们这群开 ...

  5. android中的layoutparams参数使用的简单总结

    定义: 我们可以在Android的framework中的ViewGroup类里找到定义的类: public static class LayoutParams{...} 此类有如下注释: Layout ...

  6. android中正确导入第三方jar包

    android中正确导入第三方jar包 andriod中如果引入jar包的方式不对就会出现一些奇怪的错误. 工作的时候恰好有一个jar包需要调用,结果用了很长时间才解决出现的bug. 刚开始是这样引用 ...

  7. Android中的布局优化方法

    http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...

  8. Android中如何查看内存(上)

    文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...

  9. android中少用静态变量(android静态变量static生命周期)

    在android中,要少用静态变量. 我现在做的一个应用中,之前的开发人员使用静态变量来存储cookie,这个全局的静态变量用来验证身份. 这时客户反应,应用长时间不使用,再次使用,会提示身份过期. ...

随机推荐

  1. python+requests实现接口测试 - get与post请求使用

    简介:Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 ...

  2. 运行出现Server Tomcat v8.5 Server at localhost failed to start.和A child container failed during start

    出现问题: 解决方法: 1.看servlet文件中的@WebServlet“()”,里面是否少了/字符,如图: 加上即可,有问题随时留言,欢迎您的咨询!

  3. vim 操作手册

    三种模式 编辑模式(i当前位置插入光标:a后一位置插入光标).控制模式(esc).可视模式(v). 编辑模式时可以正常输入. 控制模式是vim的核心,通过按键可以快速实现操作. 可视模式是进行选块操作 ...

  4. Python—面向对象 封装03

    接着上面的一篇继续往下: 如何隐藏 在python中用双下划线开头的方式将属性隐藏起来(设置成私有的) class A: __x = 1 # _A__x = 1 def __init__(self, ...

  5. 122. Best Time to Buy and Sell Stock II ——LeetCode

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  6. java遍历文件夹两种方式

    1:非递归方式(有点类似二叉树的非递归遍历,采用链表来存储遍历到的文件夹,如果是文件就直接输出) public void traverseFile(String path){ File[] files ...

  7. 学习Node.js知识小结

    什么是Node.js 官方解释:Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js使用了一个事件驱动.非阻塞式I/O的模型( Node.js的特性 ...

  8. GoBelieve Android SDK接入备忘

    Android SDK版本 目前SDK只支持Android 2.2或以上版本的手机系统. AndroidManifest.xml配置 以下配置可以在IMDemo/AndroidManifest.xml ...

  9. SpringBoot非官方教程 | 第三篇:SpringBoot用JdbcTemplates访问Mysql

    转载请标明出处: 原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/springboot3-JdbcTemplates-Mysql/ 本文出 ...

  10. oracle中lock和latch的用途

    本文向各位阐述Oracle的Latch机制,Latch,用金山词霸翻译是门插栓,闭锁,专业术语叫锁存器,我开始接触时就不大明白为什么不写Lock,不都是锁吗?只是翻译不同而以?研究过后才知道两者有很大 ...