Android:增加调用堆栈大小

Android:增加调用堆栈大小,android,stack-overflow,Android,Stack Overflow,我有一个具有非常复杂UI的应用程序,其中包含许多相互嵌套的布局。在创建另一个布局时,我发现了一个stackoverflower错误 奇怪的是,我创建了两个测试示例: 1) Hello world应用程序,主要活动有以下xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layou

我有一个具有非常复杂UI的应用程序,其中包含许多相互嵌套的
布局。在创建另一个布局时,我发现了一个
stackoverflower错误

奇怪的是,我创建了两个测试示例:

1) Hello world应用程序,主要活动有以下
xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <!-- ...So on 30 times... -->

                <FrameLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" >

                </FrameLayout>

            <!-- ...So on 30 times... -->

        </FrameLayout>
    </FrameLayout>
</FrameLayout>
在深度上导致大约260-270次调用的堆栈溢出错误

对于参数
=8字节
,第二个测试用例的堆栈元素每次调用的返回地址
+4字节
都需要4字节。Dalvik的
VM可能会在每个元素中保留更多的信息,但即使是
16字节/元素*260调用=大约4Kbytes
,也可以获得最大的总体堆栈大小。这似乎还不够


有没有办法增加最大堆栈大小?

如果你需要这个复杂的布局(很多人都会怀疑),你仍然可以用onCreate方法以编程方式绘制它。

你可能无法在主UI线程中增加调用堆栈大小(这是可以理解的,因为你应该在这里做尽可能少的事情),但您可以通过使用thread对象的构造函数参数在单独的线程中执行此操作:

ThreadGroup group = new ThreadGroup("threadGroup");
new Thread(group, runnableObject, "YourThreadName", 2000000).start();
在本例中,我将堆栈大小从8k(约260个调用)增加到2M(足以避免StackOverFlowException,当然,只要内存允许,您可以添加任意数量的堆栈),因此最后,对于其他读者,这是可以增加堆栈大小的方法,尽管不建议这样做,在某些情况下,它实际上是必要的,例如,一个具有大量递归调用的算法,当然,通过使用指定的堆栈大小在工作线程中执行所有艰苦的工作(正如您应该做的那样),并且只是“发布”使用带有处理程序的主UI线程或您希望用于与之交互的任何机制对UI进行更改

希望这有助于


问候

您肯定不希望这样将布局嵌套在彼此内部。如果您发现自己嵌套了三到四次,那么视图的构造效率就会越来越低,这可能会导致活动转换开始,并且可能在创建视图之前完成。这看起来很奇怪,或者完全是对活动转换的浪费


您应该将根布局设置为相对布局,并将所有框架布局作为根相对布局的子级。

没错,我认为这是一个很好的答案,尽管我不认为它保证遵守堆栈大小?如果可能的话,最好完全避免这种情况。
ThreadGroup group = new ThreadGroup("threadGroup");
new Thread(group, runnableObject, "YourThreadName", 2000000).start();