最近新作的项目上线,出现了一个让人抓狂的问题。在此记录一下!
现在的项目中,制作了一个界面非常复杂。整个结构是最外层一个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
相关推荐
在StackOverflow这个全球知名的编程问答社区中,用户们分享了丰富的技术知识和经验。...在StackOverflow的这个压缩包文件"stackoverflow-main"中,你可以找到这些宝贵的知识点的详细记录,供你学习和参考。
在Android中,通常用于缓存频繁访问的大对象,如图片。 - **实现**:当缓存容量达到设定值时,最久未使用的项会被移除以释放空间。 #### 4. HTTP协议简介 - **HTTP**(Hypertext Transfer Protocol)是一种用于...
为了有效地解决这类问题,Android开发者需要能够快速定位和理解异常堆栈中的信息。本文将详细介绍如何利用提供的资源(BolexLiu-AutoEx-607d424)来自动化这个过程。 首先,我们要理解Android应用崩溃时的日志。当...
Android 自定义滑动刷新列表片段 有 3 种状态: 1. 等待 ListAdapter 将被设置 2. ListAdapter 已设置,但 ListView 没有记录(项目) 3. ListAdapter 设置有 ListView 的记录(项目)。 此外,当将记录(项目)添加...
本文属于个人平时项目开发过程遇到的一些问题,记录下来并总结解决方案,希望能帮到大家解决问题,有些问题的解决方案是在StackoverFlow上找到的,建议大家遇到问题多去上面找,基本上都能找到解决方案的。...
了解这些异常类型及其含义对于Android开发者来说至关重要,因为它们有助于快速定位和解决程序中的问题。在编写代码时,应尽量预见可能的异常情况,使用适当的异常处理机制来增强程序的健壮性,避免因未处理的异常而...
去Stackoverflow上查了一下,发现有人回答这个问题:链接 原来一次性向数据库里插入数据的条数不能太多,上限是500条。超出会报错。 解决方案就是只好分多次插入数据库了。 您可能感兴趣的文章:SQLite教程(八):...
在Android开发中,...如果你仍然遇到困难,可以查看Android开发者文档,或者在StackOverflow等社区寻找更多关于ViewPager的使用技巧和常见问题解答。记住,对于复杂的UI交互,充分的测试和日志记录是非常重要的。
堆栈溢出错误通常发生在程序中递归调用过深或者分配的内存不足以存储所有的函数调用记录时。在Java中,当线程的调用栈超过其最大允许深度,就会抛出StackOverflowError。在Android中,这可能导致应用崩溃或性能下降...
它不仅支持主流的桌面操作系统如Windows、macOS和Linux,而且还能够适用于Android、iOS等移动平台乃至嵌入式系统。这种多平台的支持能力使得Qt成为了众多开发者的心头好,尤其是在需要构建跨平台应用程序的情况下更...
微软在Build 2016大会上宣布将Xamarin集成到Visual Studio“15”及其后续版本中,这使得C#开发者可以直接用C#编写iOS和Android原生应用代码,极大地扩展了C#的应用领域。 在微软Channel 9发布的视频中,Dustin ...
这个“Retrofit-2-basic-sample”项目是一个针对Retrofit 2(测试版)的基本用法的示例,适用于解决StackOverflow上的相关问题。 在Java编程中,Retrofit 2主要通过以下组件来工作: 1. **Retrofit Interface**: ...
这是我的六个前辈写的具有在线判断和反恐的编程考试平台防止学生通过按键记录和连续屏幕捕获作弊(使用StackOverflow,LINE等)总览三层Hacklympics-客户端(Java FX) HacklympicsAPI -RESTful API(Java 8) 夜间-...