【问题标题】:Android: Increase call stack sizeAndroid:增加调用堆栈大小
【发布时间】:2012-02-10 01:42:58
【问题描述】:

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

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

1) Hello world 应用程序,主 Activity 具有以下 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>

在绘制布局时导致 StackOverflowError(导致每个布局递归地绘制它的子级)

2) 下面的测试用例

public class TestOverflowActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overflow(0);
    }

    private void overflow(int i){
        android.util.Log.i("Stack depth:", " = " + i);
        overflow(i+1);
    }
}

导致StackOverflowError 的深度约为 260-270 次调用。

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

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

【问题讨论】:

    标签: android stack-overflow


    【解决方案1】:

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

    ThreadGroup group = new ThreadGroup("threadGroup");
    new Thread(group, runnableObject, "YourThreadName", 2000000).start();
    

    在这个示例中,我将堆栈大小从 8k(大约 260 次调用)增加到 2M(足以不出现 StackOverFlowException,当然,只要内存可以容纳,您可以添加任意数量),所以最后,对于更多读者来说,这是增加堆栈大小的方法,尽管不推荐,但在某些情况下,实际上是必要的,例如具有大量递归调用的算法,当然还有在工作人员中完成所有艰苦的工作使用您指定的堆栈大小的线程(正如您应该做的那样),并使用带有处理程序的主 UI 线程或您想用来与之交互的任何机制在 UI 中“发布”更改...

    希望对您有所帮助...

    问候!

    【讨论】:

    • 是的,我认为这是一个很好的答案,尽管我认为它不能保证遵守堆栈大小?如果可能,最好完全避免这种情况。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      如果您需要这种复杂的布局(许多人会怀疑),您仍然可以在 onCreate 方法中以编程方式绘制它。

      【讨论】:

        猜你喜欢
        • 2015-11-22
        • 2010-11-24
        • 2020-08-05
        • 2013-03-15
        • 2013-12-24
        • 2011-09-29
        • 2017-03-02
        相关资源
        最近更新 更多