2013-10-18 105 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

相关问题