堆栈溢出仅在 Android 2.3.3 设备上

我一直在研究我遇到一些错误的地方。Native Android AppAndroid 2.3.3 versions and below Android 3.0 version

我没有得到在我的代码中的确切位置,因为在Logcat中编译了每行代码,但最后得到了非常奇怪的错误,描述了下面的日志:

java.lang.StackOverflowError
at java.util.concurrent.locks.ReentrantLock$NonfairSync.tryAcquire(ReentrantLock.java:189)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1171)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
at java.util.concurrent.CopyOnWriteArrayList.removeRange(CopyOnWriteArrayList.java:569)
at java.util.concurrent.CopyOnWriteArrayList.remove(CopyOnWriteArrayList.java:366)
at java.util.concurrent.CopyOnWriteArrayList.remove(CopyOnWriteArrayList.java:376)
at android.view.ViewTreeObserver.removeOnPreDrawListener(ViewTreeObserver.java:377)

at android.widget.TextView.onDraw(TextView.java:4085)
at android.view.View.draw(View.java:6986)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)

    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)

    at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:7093)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.widget.ScrollView.draw(ScrollView.java:1421)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.d

当我检查我的代码时,我发现没有堆栈溢出的痕迹。当我在android 3.0或更高版本上运行相同的代码时,它可以有效且正确运行,但不能在android 2.3.3及以下的3.0版本上运行。请让我知道,如果有人知道这个问题??

[编辑]我正在使用Tab活动,因此主布局是Main.xml并且在该子活动中,它包含称为firstTab_Results.xml的视图,它包含一个表格布局,它确实执行inflate_table_firstTab.xml布局的最大20个视图。

[编辑2]无论如何,我都没有重复它,它将最大20次视图(inflate_table_firstTab.xml)膨胀到表格布局(firstTab_Results.xml)。

Note : Stackoverflow happens on single or dual core processor devices & without fullscreen mode .

答案 1

视图层次结构太深。以递归方式绘制层次结构时,堆栈空间会耗尽,并且无法在层次结构中更深入,如堆栈跟踪中所示。

为什么这只发生在早期的设备中,因为UI线程堆栈大小在Android 2.3设备中仅为12kB,但在更高版本的操作系统版本中为16kB(ref)。

如何降低视图层次结构深度?只要尽可能避免嵌套布局。您发布的布局太复杂,在此 Stack Overflow 模型中为您修复它们没有意义(正确执行这些布局需要一些时间,并且可能过于具体而无法帮助其他人),但以下是一些一般准则:

  • 删除不必要的布局。例如,在你的firsttab_results.xml你只需要,和上面的几乎没用。在您的中,至少有6个嵌套布局,而一个或最多两个可能就足够了。TableLayoutRelativeLayoutLinearLayoutScrollView

  • 布局中的单个子项是代码异味。大多数情况下,将子项移动到其父布局并调整带有边距的布局也可以实现相同的操作。

  • 通常几乎不需要将布局放在 .相对布局在使用相对定位和子基线对齐方式对其子项进行布局方面非常强大。RelativeLayout

  • 如果你需要一个嵌套布局只是为了一个,尝试将背景移动到例如一个与嵌套布局大小相同的布局,并将其他元素布置在上面。backgroundView

  • 注意 Android Lint 警告。该工具在检测可以简化的视图层次结构复杂性方面已经变得非常擅长。


答案 2

您有嵌套的视图层次结构,您可以在Android中使用 hierarchyViewer 查看您的视图层次结构。如果你的应用中有很多嵌套视图,那么有些设备内存很小,那些会给出异常,而对于其他设备,它会运行良好。扁平化你的视图。使用相对布局拼合视图。


推荐