什么是Android UI线程的堆栈大小限制,以及如何克服呢? [英] What is the android UI thread stack size limit and how to overcome it?

查看:1139
本文介绍了什么是Android UI线程的堆栈大小限制,以及如何克服呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到的 java.lang.StackOverflowErrors 当我视图层次正在绘制:

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

<一个href="http://stackoverflow.com/questions/2762924/java-lang-stackoverflow-error-suspected-too-many-views">Research点我的看法层次太深为Android来处理。事实上,使用的层次浏览器,我可以看到我的时间最长的嵌套的 19 的意见(!)

我的应用程序看起来有点像谷歌Play商店的应用程序(使用刷卡标签)。每个标签是一个片段视图寻呼机内嵌套的片段 - 使用V4支持和HoloEverywhere。显然,这是为什么我的等级已经变得有点疯狂。

我的问题:

  1. 什么是的真正的堆栈大小的限制?我发现没有办法来衡量UI线程的堆栈大小。网上说8KB的一些传闻,但有没有办法来衡量这个的准确地的一些器件样品?

  2. 是否与操作系统版本堆栈大小限制的变化?在同一层次做的没有的崩溃的4.0.3设备上,但不会崩溃在2.3.3设备(相同的硬件)。这是为什么呢?

  3. 有没有除了手工优化,层次中的任何解决方案?我发现没有办法来增加的可笑的小叠UI线程的。很抱歉,但60-100栈帧的限制是一个笑话。

  4. 假设有对#3没有奇迹的解决方案,对于其中的核心层次结构的优化应该做的任何建议?

  5. 疯狂的想法 - 我注意到,每个视图层增加约3函数调用(View.draw,ViewGroup.dispatchDraw,ViewGroup.drawChild)。也许我可以做我自己的ViewGroup实现(自定义布局),也就是减少浪费堆栈拉制过程中()?

解决方案

我相信,主线程的堆栈由JVM控制 - 在Android的情况下 - 的Dalvik JVM。如果我没有记错的相关常量在的Dalvik / VM / Thread.h 的#define kDefaultStackSize <发现/ P>

通过Dalvik的来源历史浏览堆栈大小:

那么有多少嵌套的观点,你才能有:

不可能准确地说。假设堆栈大小如上所述,这一切都取决于有多少函数调用你有你最深的嵌套(多少变数每个功能需要,等等)。看来,问题的领域是当正在绘制的意见,从 android.view.ViewRoot.draw()。每个视图调用它的孩子们的画,并进入深如你最深的嵌套。

我会在上面出现的所有边界组中的设备执行至少实证检验。看来,使用模拟器给出准确的结果(虽然我只比原生x86模拟器到真实设备)。

请记住,优化,如何实际的小部件/布局的实施也可能会影响此。话虽如此,我相信大多数的堆栈空间是由每一个布局层次增加约3嵌套函数吃过来电:画() - > dispatchDraw () - > drawChild()键,这样的设计并没有从2.3太多的改变 - 4.2

I'm getting java.lang.StackOverflowErrors when my view hierarchy is being 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)
...

Research points to my view hierarchy being too deep for Android to handle. Indeed, using Hierarchy Viewer, I can see that my longest nesting is 19 views (!)

My app looks somewhat like the Google Play store app (with swipe tabs). Every tab is a nested fragment inside a fragment view pager - using v4 support and HoloEverywhere. Obviously, this is why my hierarchy has gotten a bit crazy.

My questions:

  1. What is the real stack size limit? I found no way to measure the stack size of the UI thread. Some rumors on the net say 8KB, but is there a way to measure this accurately on some sample devices?

  2. Does the stack size limit change with OS ver? The same hierarchy does not crash on an 4.0.3 device but does crash on a 2.3.3 device (identical hardware). Why is that?

  3. Is there any solution except optimizing the hierarchy manually? I found no way to increase the ridiculously small stack of the UI thread. Sorry, but 60-100 stack frame limit is a joke.

  4. Assuming there's no miracle solution on #3, any recommendations for where the core hierarchy optimization should be done?

  5. Crazy idea - I noticed that every view layer adds about 3 function calls (View.draw, ViewGroup.dispatchDraw, ViewGroup.drawChild). Maybe I can make my own ViewGroup implementation (custom layouts) that is less wasteful on stack during draw()?

解决方案

I believe that the main thread's stack is controlled by the JVM - in Android's case - Dalvik JVM. The relevant constant if I'm not mistaken is found in dalvik/vm/Thread.h under #define kDefaultStackSize

Browsing for stack sizes through the dalvik source history:

So how many nested views can you have:

Impossible to say accurately. Assuming the stack sizes are as described above, it all depends on how many function calls you have in your deepest nesting (and how many variables each function takes, etc). It seems that the problematic area is when the views are being drawn, starting with android.view.ViewRoot.draw(). Each view calls the draw of its children and it goes as deep as your deepest nesting.

I would perform empirical tests at least on the devices appearing in all the boundary groups above. It seems that using the emulator gives accurate results (although I've only compared the native x86 emulator to a real device).

Keep in mind that optimizations to how the actual widgets / layouts are implemented may also influence this. Having said that, I believe that most of the stack space is eaten by every layout hierarchy adding about 3 nested function calls: draw() -> dispatchDraw() -> drawChild() and this design hasn't changed much from 2.3 - 4.2.

这篇关于什么是Android UI线程的堆栈大小限制,以及如何克服呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆