2013-10-18 62 views
9

我有一個安裝了Android SDK的應用程序編譯並與目標SDK 4.3一起運行的問題。該應用程序有兩個活動,MainActivity也是啓動器活動和SecondActivity。兩者都使用碎片。爲了支持較老的設備,也使用支持庫。java.lang.IllegalStateException:已添加片段

在下面的情況下它涉及到「IllegalStateException:Fragment已添加」錯誤。

1)啓動應用程序 - > MainActivity示
2)切換到SecondActivity與意圖
3)按主頁按鈕
4)等待更長的時間(在24小時測試)
5 )再次按下應用程序圖標 - >例外。如果時間較短,SecondActivity會如預期顯示。

在分片處理過程中,我讀了很多IllegalStateExceptions,但所有這些都指向replace()方法的問題。在Stacktrace中,我自己的代碼永遠不會被調用。

的Fragement在活動比較的onCreate()方法添加:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(..); 
    ListFragment listFragment = this.getCaptureListFragment(); 
    FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
    tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag"); 
    tx.commit(); 
} 

private ListFragment getListFragment() { 
    ListFragment listFragment = (ListFragment) this.getSupportFragmentManager().findFragmentByTag("list_fragment_tag"); 
    if (listFragment == null) { 
     listFragment = new ListFragment(); 
    } 
    return listFragment; 
} 


java.lang.RuntimeException: Unable to start activity ComponentInfo{de.myexample.demo/de.myexample.demo.ui.SecondActivity}: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
    at android.app.ActivityThread.access$600(ActivityThread.java:141) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:5103) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175) 
    at android.support.v4.app.BackStackRecord.run(SourceFile:616) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460) 
    at android.support.v4.app.FragmentActivity.onStart(SourceFile:556) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171) 
    at android.app.Activity.performStart(Activity.java:5143) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
    ... 11 more 
java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175) 
    at android.support.v4.app.BackStackRecord.run(SourceFile:616) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460) 
    at android.support.v4.app.FragmentActivity.onStart(SourceFile:556) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171) 
    at android.app.Activity.performStart(Activity.java:5143) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
    at android.app.ActivityThread.access$600(ActivityThread.java:141) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:5103) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 
+0

哪裏是來回的setContentView活動? – Raghunandan

+0

嘗試使用tx.replace(R.id.MainFragmentContainer,listFragment);而不是使用tx.add()方法。閱讀[this](http://developer.android.com/guide/components/fragments.html)。更多的片段 –

+0

謝謝@Raghunandan。我在帖子中添加了缺失的行。 – creaity

回答

12

好了,解決了我自己。

我把所有片段放在onPause()中,並將狀態存儲在一些布爾值中。根據布爾值,碎片被放入onResume()中。無論活動在後臺運行多長時間,發射都是穩定的。

boolean addList = false; 

@Override 
protected void onResume() { 
    FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
    if (this.addList) { 
     ListFragment list = this.getListFragment(); 
     tx.add(R.id.MainFragmentContainer, list, "list_fragment_tag"); 
    } 

    tx.commit(); 
    super.onResume(); 

    this.addList = false; 

} 

@Override 
protected void onPause() { 
    this.addList = this.getListFragment().isAdded(); 
    ... 
    if (this.addList) { 
     FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
     tx.remove(this.getListFragment()); 
     tx.commit(); 
    } 
    this.getSupportFragmentManager().executePendingTransactions(); 
    super.onPause(); 

} 

也許這可以幫助別人同樣的問題

0

片段管理器保存其狀態時退出。所以你不必再添加你的片段。

這樣做:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(..); 

    if (savedInstanceState == null) { 
     ListFragment listFragment = this.getCaptureListFragment(); 
     FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
     tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag"); 
     tx.commit(); 
    } 
} 
+0

感謝您的答案。它有所幫助,但並不完全。在Android 4.1上,它有訣竅。但是在4.4 KitKat設備上,活動是空的,沒有看到碎片。但看起來,這種方式比手動移除好得多。也許,我可以在更新的設備上手動刪除片段,如果...我必須做更多的測試。但是它們非常耗時,因爲我必須至少等待24小時纔會發現問題 – creaity

8

爲了再現這一點,人們可以激活設置「不保留活動」 - >開發人員選項。然後暫停並恢復活動。

這使您不必等待24小時:)

+0

它不適用於我:( –

-3

這是沒有必要的檢查碎片的增加狀態來創建新的布爾領域。碎片中也有一個方法。 只是用它: myFragment.isAdded()

+0

布爾型不用於存儲片段的狀態被添加。它用於存儲之前的狀態(請參閱我的onPause()方法)。我認爲你不明白這個問題。 – creaity

+1

是的,我現在讀的更加謹慎,我很抱歉,你是對的。 – serefakyuz

相關問題