14

我一直在研究Native Android App我面临一些错误的地方Android 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

当我检查我的代码时,我没有发现 stackoverflow 的踪迹。当我在 android 3.0 或更高版本上运行相同的代码时,它可以有效且正确地运行,但不能在 android 2.3.3 和 3.0 以下版本上运行。如果有人知道这个问题,请告诉我??

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

[编辑 2] 无论如何我都不会递归它,它会将 Max 20 个视图(inflate_table_firstTab.xml)膨胀到表格布局(firstTab_Results.xml)。

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

5 回答 5

19

您的视图层次结构太深。递归绘制层次结构时,您会用完堆栈空间,并且无法深入层次结构,如堆栈跟踪中所观察到的。

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

如何减少视图层次深度?尽可能简单地避免嵌套布局。您发布的布局过于复杂,没有必要在 Stack Overflow 模型中为您修复它们(需要一些时间才能正确完成,而且可能过于具体而无法帮助其他人),但这里有一些一般准则:

  • 删除不必要的布局。例如,在您的 firsttab_results.xml 中,您只需要顶部的TableLayoutRelativeLayoutLinearLayout几乎没用。在您ScrollView的情况下,至少有 6 个嵌套布局,而一个或最多两个可能就足够了。

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

  • 通常很少需要将布局放在RelativeLayout. 相对布局在使用相对定位和子基线对齐来布置其子项方面非常强大。

  • 如果您只需要一个嵌套布局background,请尝试将背景移动到例如View与嵌套布局大小相同的 a,然后在其上布置其他元素。

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

于 2013-11-08T08:07:38.533 回答
5

你有嵌套的视图层次结构,你可以在android中使用hierarchyViewer查看你的视图层次结构。如果您的应用程序中有许多嵌套视图,那么某些内存较小的设备会出现异常,而其他设备则运行良好。扁平化您的视图。使用RelativeLayout来展平视图。

于 2013-11-04T10:40:12.010 回答
1

我认为您不会因为“嵌套”您的观点而看到您的错误。我认为使用早期设备在其库中无法访问的东西可能是一个问题,并且您的 ide 没有捕捉到它,或者您有 lint 警告并且忽略了它们。尝试查看您的 lint 警告,看看它是否提到某些视图或 api 在早期版本中不可用。

于 2013-11-12T18:20:46.843 回答
1

Android 上的堆栈限制为 8K,即使在至少具有 2GB RAM 的三星 Galaxy S3 上也是如此。我不知道它是否因设备而异。我不知道为什么,我问,他们关闭了我的问题

您的 Main.xml 非常嵌套,无论使用什么代码都可能导致堆栈溢出。每个嵌套级别使用的堆栈数量取决于实现,这就是它发生在一个版本而不是另一个版本上的原因。一个版本可能调用 5 个函数链,然后处理嵌套 XML 的下一级,依此类推,一个版本可能会链接 20 个函数。

于 2013-11-14T16:59:04.993 回答
0

您是否使用递归来构建视图层次结构?我几乎从来没有看到StackOverflowError没有递归。

于 2013-11-08T06:41:09.233 回答