2012-01-13 176 views
9

我有非常複雜的UI的應用程序,在含有許多彼此嵌套layouts一個。雖然創建另一個佈局,我得了StackOverflowError的Android:增加調用堆棧大小

想知道,我創建了兩個測試的例子:

1)你好世界下面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 bytes。有可能Dalvik's虛擬機會在每個元素中保留一些信息,但即使是16 bytes per element * 260 calls = about 4Kbytes也是最大的整體堆棧大小。這似乎不夠。

有沒有辦法增加最大堆棧大小?

回答

22

你可能不能夠增加調用堆棧大小在主UI線程(因爲你應該做的幾件事情儘可能在這裏這是可以理解),但你可以通過使用做一個單獨的線程Thread對象的構造函數參數:

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

有了這個例子中,我增加了我的堆棧大小從8K(約260呼叫)到2M(足夠不要讓StackOverFlowException,當然你也可以添加你想要儘可能多隻要內存可以接受它),所以最終,對於更多讀者來說,這是您可以增加堆棧大小的方式,儘管不推薦使用,在某些情況下,它實際上是必需的,例如,具有廣泛遞歸的算法當然也可以通過在工作線程中完成所有的工作(如你應該做的),使用指定的堆棧大小,並使用主UI線程與處理程序或任何您想要的機制「發佈」UI中的更改用來與它進行交互...

希望這有助於...

問候!

+0

沒錯,我認爲這是一個很好的答案,但我不認爲它會保證遵守堆棧大小?如果可能的話,最好儘量避免這種情況。 – 2013-11-16 00:24:20

+0

完全同意,但如果需要作爲最後資源,可以知道是可能的。 – 2013-11-17 01:19:41

-1

如果需要這種複雜的佈局(如很多人會懷疑),你仍然可以做它programticaly在onCreate方法。

0

你肯定不希望對方內線像鳥巢佈局。如果你發現自己嵌套了三到四次,那麼視圖的構造就變得越來越低效,這可能導致活動轉換開始,並可能在視圖創建之前完成。這看起來很奇怪,或者完全浪費了活動轉換。

你應該讓你的根佈局相對佈局,並把所有的幀佈局爲根相對佈局的孩子。