我在主 UI 线程中遇到 StackOverflowErrors 问题(相关问题 https://stackoverflow.com/questions/16843357/what-is-the-android-ui-thread-stack-size-limit-and-how-to-overcome-it)。我的应用程序面向 Android 2.3+。在 Android 4 上一切正常,但在 2.3.3 上绘制视图布局时出现崩溃。
显而易见的答案是优化我的视图布局并减少嵌套视图的数量。这是一个问题,因为大量的视图是由于我使用选项卡的支持库和片段 - 这是推荐的方法。我不想仅仅因为旧版本的操作系统有一个小堆栈就改变我的设计并删除片段。
我正在寻找增加 UI 线程堆栈大小的方法。我见过answers https://stackoverflow.com/a/8865363/1025458这是不可能的,而且我知道清单中没有简单的设置可以做到这一点。但是,我仍然不满意没有手动解决方法。
到目前为止我最好的想法:
创建一个具有更大堆栈的新工作线程(Thread 类)。可以增加工作线程的堆栈大小。然后,以某种方式将该线程转换为新的 UI 线程。如何?
浏览 Android 源代码android.app.Activity http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/app/Activity.java?av=f.attach(..) 我已经看到一个 Activity 将自身附加到 UI 线程。也许有某种方法可以替换它所附加的线程并将其更改为我的“新”UI 线程
更深入一点android.app.ActivityThread http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/app/ActivityThread.java?av=f.startActivityNow(..),也许我可以手动启动我的活动。创建活动后,它会自动将自身附加到创建它的线程。也许如果我从新的 UI 线程运行它,它就会起作用。
如果我创建一个新的 UI 线程,我将必须为其手动创建 Looper。我开始了解需要创建什么android.app.ActivityThread http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/app/ActivityThread.java?av=f。主要的(..)
其他想法:
手动捕获 StackOverflowError,并在发生时异步移动调用,以便它们具有较小的堆栈。我见过这个好主意here https://stackoverflow.com/questions/6705425/fixing-the-stackoverflow-error/14885190#14885190但我无法让它发挥作用。
NDK 线程(通过 JNI)具有大型堆栈。我考虑过使用它们来为我谋取利益,但我看不出有什么办法可以做到这一点。通过 JNI 的所有调用都在其自己的线程上执行,因此我看不到如何使用 NDK 线程进行 UI 访问。
So..
除了说这是一个非常糟糕的主意之外,还有其他建议或提示吗?你能找到做过类似事情的人吗?我不能..
可悲的是,CommonsWare 犯了一个错误。仔细检查发现,Android 2.x 上的默认堆栈大小为 12KB,而在 Android 4.x 中已增加到 16KB。这意味着核心团队意识到了小堆栈问题并修复了它。遗憾的是,正是这些额外的 4KB 导致了崩溃。
此外,如果您使用 ABS 等通用库并支持 v4 - 每当您使用片段时,这些库都会向您的布局添加额外的视图。由于我们大多数人都依赖这些库,因此说可以使用 1 个视图轻松添加片段是完全错误的。如果您使用 ABS+support lib,您将为每个片段支付 3 次观看费用。您将从至少 5 个视图开始(对于 ABS 布局)。
关于手动创建 UI 线程,这可能是可能的,并且可能不需要 root 设备或更改其固件。这些也是可能不正确的大胆言论。
最后,我决定不创建自己的具有大堆栈的 UI 线程。相反,我选择从代码中完全放弃使用片段。这在我的布局中总共节省了 5 个视图。片段为您提供的所有内容也可以通过手动添加 ViewGroup 来完成。只是多了一点代码,但并没有太复杂。似乎碎片有点无用,如果你没有奢侈地使用它们 - 那就是第一个被削减的地方。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)